Many calls to corporate Help desks involve Windows 2000 and Windows NT 4.0 account-management tasks that require a systems administrator's intervention, such as recovering a forgotten password. A self-service account-administration model might be just the ticket to improve IT staffing efficiency and reduce costs—significant benefits in today's volatile economy. Such a model capitalizes on the concept of impersonation in COM+ to let users reset their passwords and unlock their AD user accounts. If your high-security environment precludes letting users administer their accounts, you can leverage the same model to increase security by using stored personal data to verify the identity of users who call the Help desk.

How do you create a secure self-service account-administration system? You can purchase a prebuilt system from an Independent Software Vendor (ISV), but in many circumstances, you can use ActiveX Data Objects (ADO), Active Directory Service Interfaces (ADSI), and Active Server Pages (ASP) to develop a basic Web-based solution for less money. In general, such a solution must perform three fundamental activities: data collection, user authentication, and account administration. First, you need a data-collection application that you can use to populate a database with information that uniquely identifies users. Second, you must develop a secure user-authentication mechanism that uses this data rather than traditional username and password credentials. Third, you can extend the authentication mechanism to unlock an account or reset a password on the user's behalf. I've created a complete sample solution (including documented source code) that you can download and adapt to your environment. To download the necessary files, go to, InstantDoc ID 26696, and download the file. For information about implementing the applications, see the Web-exclusive sidebar "Sample Self-Service Account-Administration Application" (, InstantDoc ID 26695).

Step 1: Data Collection
To determine the data you need to collect, first consider how you can best authenticate users without relying on traditional username and password credentials. Many nontechnical instances of this type of authentication exist. For example, a telephone conversation with a customer-service agent at a financial institution inevitably begins with a few questions that help the agent feel relatively secure about the caller's identity. Some institutions consider knowledge of address and account number sufficient, whereas others ask for personal information such as mother's maiden name or an account password. These basic questions help provide human-to-human authentication. The two parties can then continue with the business at hand, whether it be trading securities or discussing an account balance.

To begin collecting user secrets, develop an NTFS-secured Web page (data_collection.asp in the sample application) that presents four to six personal questions (i.e., challenges), as Figure 1, page 68, shows. These challenges need to meet several criteria. The captured secrets (i.e., responses) should be things that only the user knows, can't be found in corporate databases or public information stores, and can't be socially engineered (i.e., intruders can't discover the answers through guesswork, casual conversation, or observance of the user's physical characteristics). Also, the responses should be static (i.e., the data won't change should the user change job function or location). These criteria preclude questions about such things as the department the user works in, the user's home address, or a telephone number. Coming up with challenges that meet these criteria can be tedious—especially in global organizations, in which some users don't have a social security or driver's license number that you can use.

Almost everyone, however, can provide genealogical information such as parents' anniversary, mother's birth year, or maternal grandfather's name. Such information is difficult to discover through casual acquaintance and therefore can be useful static data. You might also consider challenges that are open to user interpretation, such as a request for a memorable date. Such questions don't specify the type of date, which can be anything from a birth date to an anniversary date to a date of hire. Or, you can let users provide both a question and answer. This method is probably the most secure because imposters would need to discover both the challenge and response. However, deriving challenges that meet all the necessary criteria can be difficult, so leaving the question solely in users' hands might not be the best choice. To ensure that the data is static and difficult to discover, balance user-defined and predefined challenges.

To build the data-collection application, you need to create a three-tier architecture that consists of a database back end, a COM object that interacts with the database, and ASP code that creates the UI. In the sample application, the included database defines two tables: Predefined_Questions and Collected_Data. Predefined_Questions, which Web Table 1 (, InstantDoc ID 26696) shows, stores the predefined questions that the script presents to the user (e.g., What is your mother's maiden name?). Collected_Data, which Web Table 2 shows, stores user responses. The sample script uses a Microsoft Access 2000 database, but you can easily modify the COM object's ADO code to use any ODBC-compliant database back end.

The data-collection effort begins when users navigate to data_collection.asp, which contains the code that Web Listing 1 (, InstantDoc ID 26696) shows. The script instantiates authenticate.dll through the include file, which Listing 1 shows.

Data_collection.asp then uses the code at callout A in Listing 2 to call the GetNumberOfPredefinedQuestions method. The script uses this method to determine the number of predefined questions currently stored in the database. As the code at callout B in Listing 2 shows, the script then uses that value in a loop to call the DisplayPredefinedQuestion method and to generate the HTML code that presents the predefined challenges and corresponding response text boxes.

Data_collection.asp also uses the code that Listing 3 shows to present a custom challenge and response pairing. After the user provides the information and submits the form, the script posts the data to confirmation.asp, which Web Listing 2 shows.

If confirmation.asp finds data in each field, it calls the COM server's WriteDB method, which uses an RC4 encryption algorithm to encrypt the data, then Base64 encodes the result, as Listing 4 shows, ensuring that the data will be stored securely in the database. (If an intruder were to compromise the native database security, he or she would also need to break the encryption algorithm to obtain the value of the stored data.) The WriteDB function takes UID as an argument. The sample .asp files define UID as Request.ServerVariables("Auth_User"), which uses the username that the user presents for authentication. Microsoft Internet Information Services (IIS) 5.0 can permit either a standard username (i.e., domain\username) or a user principal name (UPN). In Windows XP and Win2K environments, the UPN is an excellent choice because it permits a simple mechanism for presenting usernames without requiring users to know anything other than their email address. Ideally, you will match the mechanism they use to log on to their workstations. If any data is missing, confirmation.asp calls the ValidationError subroutine, which Listing 5 shows, to redirect the user to data_collection.asp.

Authenticate.dll encapsulates most of the application's crucial functions. The sample scripts include full commented source code for authenticate.dll, in case you want to modify the encryption keys or algorithm. You can now use the stored secrets to authenticate users through a self-service application or over the telephone.

Step 2: User Authentication
One obvious question that users will have about any self-service account-administration application is, "How can I administer my account if I can't log on?" If users can't log on to a domain account—because of a forgotten password, for example—they can use any Web browser (e.g., a colleague's workstation) to access the account-administration application. (More robust alternatives, such as integrating with an interactive voice-response system or modifying the logon screen, are available through ISVs or—if talent and resources permit—further internal engineering and development.) Because the application doesn't use a traditional authentication mechanism, you need to configure all the administration Web pages to use Anonymous access.

The sample administration application begins with ssa.asp, which Web Listing 3 shows. This initial authentication page uses the code that Listing 6, page 70, shows to prompt the user to present a bit of basic information, such as the user's UPN, email address, domain name/username combination, employee ID number, or some other unique enterprise identifier. For extra security, you can also consider presenting one of the authentication questions (e.g., mother's maiden name), as Figure 2 shows.

This initial page prevents enterprise guests from examining the full set of criteria you use to authenticate users and facilitates the use of user-specific challenge and response pairings. A hidden field on this page stores the number of the question presented in the initial authentication so that the question isn't repeated on the main authentication page.

The user submits the form, which posts the data to ssa_confirmation.asp, as Figure 3, page 70, shows. This main authentication page uses the code that Web Listing 4 shows to present the remaining authentication questions and the options for the action the user wants to perform (e.g., removing the lockout condition, resetting the password). The user selects an action, answers each question, then submits the form. The application passes the user responses to the COM server for processing. In addition to basic validation of the initial form's elements, ssa_confirmation.asp calls the COM server's AuthenticateChallengeResponsePairing method to verify the posted information against the values in the database. AuthenticateChallengeResponsePairing takes the username, question number, and user response; encrypts the username and searches for it in the database; returns the matching record; then decrypts the data. If the user-provided data matches the corresponding user data in the database, the application returns a Boolean value of True and the system considers the user authenticated.

If you use the application at a Help desk to aid in caller verification (rather than letting users have direct access to the application), Help desk staff members can simply ask for the prompted information over the telephone to authenticate the caller, then administer the account on the caller's behalf. Best of all, Help desk staff don't need administrative rights to reset passwords or unlock accounts.

Step 3: Account Administration
After the application authenticates a user, it posts the validated data to authenticate.asp, which Web Listing 5 shows. This script validates the information again, assembles a delimited string with the user-provided secrets, then passes that string and the action to be performed to the AuthenticateUser function. The AuthenticateUser method compares each user response with the data in the database, then calls the COM server's AuthenticateUser method to perform the chosen action.

Typically, resetting a password would require the user (or the Help desk staff member entering the information on the user's behalf) to have Administrative rights; all account management operations require some level of administrative rights to perform the requested action. However, you implement this application as a COM/COM+ object and run the COM server under the context of a Win2K Component Services package (on Win2K and IIS 5.0 systems) or a Microsoft Transaction Server (MTS) package (on NT 4.0 and Internet Information Server—IIS—4.0 systems) to which you've assigned an administrative account's identity (see "Sample Self-Service Account-Administration Application" for details). Therefore, the user (e.g., the IUSR account) can run the AuthenticateUser function in the context of a more powerful account. To ensure security, the AuthenticateUser method requires the target user's secrets to be passed into the method as well. The script validates this data before unlocking the account or resetting the password. The concept of COM delegation is too complex to explain in detail in this article. However, "Making the Transition: Multi-Tier Development for System Administrators" (, which is an excerpt from my book Windows NT/2000: ADSI Scripting for System Administration (Macmillan Technical Publishing, 2000), provides a complete tutorial.

The application then uses ADSI and the COM server to return a Boolean value representing the verification event and unlocks the account, resets the password, or performs any combination thereof. If all is successful, the application displays a confirmation message letting the user know that the account has been authenticated and that the account was unlocked or the new password was reset, as Figure 4 shows.

Help Users Help Themselves
In today's soft economy, a self-service administration model can free up IT staff time, cutting costs and helping your organization remain competitive. Whether you want to reduce costs and systems-administrator workloads or increase Help desk security, a self-service application can increase the level of service you provide to users.