Tom Moran
Jeff Sandquist
Microsoft Corporation
January 25, 1999
The following article was originally published in the Site Builder Network Magazine "Servin' It Up" column (now MSDN Online Voices "Servin' It Up" column).
How are those New Year's resolutions going? Go ahead: Burn one, and throw that patch away. Pull the shirt off the handlebars, and fold up that Total Gym 2000. Admit it -- your 500 Easy Meals under 50 Calories recipe book is propping up your monitor so your neck doesn't hurt so badly after a 12-hour stint of Age of Empires. But don't give up on that resolution about becoming a star ASP programmer.
This month, Jeff Sandquist, a friend and coworker, is helping with this article. Jeff comes from Developer Support, and he's originally from Canada, so this is technically my first effort toward a truly international column. We would like to introduce you to Active Directory Service Interfaces (ADSI), and to do that, we have a small project in mind that will take this month and next month to complete.
You are responsible for a production Web server. You want to enable a certain group of users, probably administrators, to automatically create a virtual directory for a particular developer, and at the same time, to set the appropriate permissions. You don't have FrontPage Server Extensions installed on the server, so you can't use Visual InterDev® to create the applications. Besides, you don't want to have to respond personally to everyone and fire up Visual InterDev whenever someone makes a request for a new app. ADSI and Active Server Pages (ASP) technology, plus a little DOS, will come to the rescue.
We will validate the user as a member of a privileged group. Then we will prepare a form that populates a list box with the usernames of everyone in another user group. The form will allow you to pick a user, and pick privileges for that user's new virtual directory. This is basically what we'll cover this month. Next month, we'll take the data from the form and create the directory with all appropriate permissions. You can see that this application could easily be modified to allow just about anyone to automatically request and create a virtual directory -- a real time-saver for a busy administrator
We have created two groups on our Windows NT Server. To run the example, you'll need to do the same -- or you can use existing groups on your server and change their names in the code:
You can't use Personal Web Server on Windows 98 to do this. It requires Windows NT Server and Internet Information Server (IIS) 4.0.
First, we'll need to force authentication on the Web page. We do this by changing the HTTP headers to force authorization. Copy the following code into an ASP file.
<%@ Language=VBScript %> <% Option Explicit %> <% ' Force authentication If Request.ServerVariables("LOGON_USER") = "" Then Response.Status = "401 Authorization Required" Response.End End If %>
Next, we'll declare some variables, since all good ASP programmers use option explicit, and we'll dynamically build both the machine object and the current user's Active Directory Services (ADS) path. The machine object is used for only one purpose: to get the namespace. Why is the namespace important? It is the key to accessing all group collection -- and we'll use it quite a bit further down in the code. The user's ADS path is used to validate that person as a member of a specific group.
Insert the following just below your last bit of code.
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> <TITLE>Web Administrator</TITLE> </HEAD> <BODY> <% Dim strServerName 'NT local machine name Dim strGroup 'NT group name Dim strMachineObject 'ADSI machine object path Dim strUserADsPath 'ADSI user ads path Dim objMachine 'ADSI machine object Dim strNameSpace 'ADSI namespace Dim objMember 'ADSI member object Dim objGroup 'ADSI group object Dim strADSPath 'ADS path Dim bolAuthenticated 'Authentication flag Dim strMember 'NT user name for group member ' Build MachineObject strServerName = Request.ServerVariables("SERVER_NAME") strMachineObject = "WinNT://" & strServerName
Note that we have to change the slashes returned from logon to match the ADS convention.
' Build Current User's UserAdsPath strUserAdsPath = "WinNT://" & Request.ServerVariables("LOGON_USER") strUserAdsPath = Replace(strUserAdsPath, "\", "/")
Next, we get the namespace (always setting our objects to nothing when we're done with them, of course). We do this dynamically, so the code can easily move from our server to yours.
' Get NameSpace from Machine Object Set objMachine = GetObject(strMachineObject) strNameSpace = objMachine.Parent Set objMachine = Nothing ' Build Name Space for Group Object strGroup = "Web Administrators" strNameSpace = strNameSpace & "/" & strServername
Now that we have the namespace, we need to ensure that the authenticated user is a member of the Web Administrators group. If so, we set the bolAuthenticated flag to true.
' Iterate through the Web Administrators group and ensure ' that the user visiting this page is a member Set objGroup = GetObject(strNameSpace & "/" & strGroup) For Each objMember in objGroup.Members If objMember.ADsPath = strUserAdsPath then bolAuthenticated = "True" Exit for End If Next Set objGroup = Nothing
First, we'll make sure that the user has been authenticated as part of the Web Administrators group by checking the auth flag. Next, we will dynamically build a list of folks for the Web administrator to choose from by retrieving the members of the Intranet Developers group. We retrieve the value of each group member's AdsPath and change it to a domain\user format. These are the folks who will get permission (next month) for the new virtual directory. We'll also give administrators the option of turning on script permissions, and allow them to submit the form. Additional functionality would be to set write permissions, allowing Visual InterDev to deploy with the deployment explorer.
If bolAuthenticated then %> <CENTER> <FORM ACTION="http://sand1/ServinSecure/CreateDirectory.asp" METHOD="POST"> <TABLE WIDTH=600 BORDER=0 CELLSPACING=1 CELLPADDING=1> <TR> <TD ALIGN="RIGHT" NOWRAP> Virtual Directory To Create</TD> <TD ALIGN="LEFT" NOWRAP> <INPUT type="text" id=textVirtualDirectory name=textVirtualDirectory></TD> </TR> <TR> <TD ALIGN="RIGHT" NOWRAP>Developer</TD> <TD ALIGN="LEFT" NOWRAP> <SELECT size=1 id=selectOwner name=selectOwner> <% strGroup = "Intranet Developers" ' Iterate through the Users group and get a list of people ' who are a member of that group. Set objGroup = GetObject(strNameSpace& "/" & strGroup) For Each objMember in objGroup.Members strMember = Replace(objMember.ADsPath, "/", "\") strMember = Mid(strMember, 9, Len(strMember)) Response.Write "<OPTION VALUE=" & strMember & ">" Response.Write strMember Response.Write "</OPTION>" Next Set objGroup = Nothing %> </SELECT> </TD> </TR> <TR> <TD ALIGN="RIGHT" NOWRAP> Turn on Script Permissions</TD> <TD ALIGN="LEFT" NOWRAP> <INPUT type="checkbox" id=checkboxScript name=checkboxScript></TD> </TR> <TR> <TD ALIGN="RIGHT" NOWRAP> <INPUT type="reset" value="Reset" id=reset1 name=reset1></TD> <TD ALIGN="LEFT" NOWRAP> <INPUT type="submit" value="Submit" id=submit1 name=submit1></TD> </TR> </TABLE> </FORM> </CENTER>
And if those users failed authentication as members of Web administrators, we say goodbye with the following code:
<% Else %> <P>I am sorry you do not have access to this page. Please contact the Web site administrators for more information</P> <% End If %> </BODY> </HTML>
If you want a really great sample that does just about everything, check out your Windows NT Option Pack. It has the complete source for Internet Service Manager (HTML).
"So where does that DOS part come in?" you ask. You'll have to wait until next month, when we show you how to use this form, ADSI, and some magic tricks to actually create the directory under IIS and assign the appropriate permissions.
Until then,
Tom and Jeff
Tom Moran is a program manager with Microsoft Developer Support and spends a lot of time hanging out with the MSDN Online Web Workshop folks.
Jeff Sandquist (one of Microsoft's finest Canucks) is a member of Developer Support's Active Server Pages Escalation Team and Commander in Chief of the Visual InterDev MVP program.