How to Access NDS from HTML or ASP, Part 3
Articles and Tips: article
01 May 2001
This is Part 3 of our series on how to access NDS from HTML or ASP. This article discusses using AX NWDir in ASP. For Part 2 of this article, see http://support.novell.com/techcenter/articles/ana20010306.html.
Using AX NWDir in ASP
So far we have been using scripting on the client side only. In fact, our Web server was used only as an HTML document store, which provides documents each time the client sends the request.But certainly there are some situations or problems we face daily, where it would be very efficient to have some kind of server-side scripting instead of client-side scripting. By "server-side scripting," I mean scripting which is done on the Web server. Server-side scripting would allow us to conditionally show or hide the content of the requested document, it would allow us to create personalized view of the content for different visitors. It would also reduce frequent downloading of HTML documents and the total number of HTML documents we have to handle when creating HTML applications.
Server-side scripting is exactly what Microsoft's Active Server Pages (ASP) technology offers. ASP is server-side scripting environment that enables us to create and run dynamic and interactive Web-server applications. To use Active Server Pages, we have a choice to run one of the Microsoft's Web servers- Internet Information Services (IIS), Windows NT Peer Web Services, or Windows 95 Personal Web Server.
What ASP does is basically very simple: whenever the client asks the Web server for downloading of an ASP document, the document is not sent directly to the client but rather it is sent by Web server to the ASP engine (ASP.DLL). Any code in this document which belongs exclusively to ASP is processed by the ASP engine, no matter whether it is scripting or non-scripting code. Only the outputs of the ASP engine in the form of a common HTML document are finally assembled and sent as a response to the client.
But how does the ASP engine recognize the code that should be processed as an ASP code, the code that belongs exclusively to the ASP? ASP uses <% and %< delimiters to enclose ASP scripting commands. Everything enclosed within these delimiters is supposed to be ASP code and is processed directly on the server. ASP delimiters are used here in the same way comment delimiters <!-- and --< in HTML scripting can be used to recognize (in fact, to hide) scripting code from being seen by <dummy< HTML browsers.
ASP includes six standard built-in objects for use in an ASP application:
Request to get the information from the remote user.
Response to send the information to the user.
Session to store and handle the information for the current user of an ASP application.
Application to store, handle and share the information belonging to ASP application among all its users.
Server to control the ASP server.
ObjectContext used for transaction support.
When a visitor connects to the Web server and initially visits the Web home ASP page, he or she creates an ASP session on the server. The built-in session object is used here to keep track of user activities. You can imagine that the ASP built-in session object is instantiated on the server each time a new visitor connects and asks for the ASP home page. This session object stores information about user's session. Because ASP differentiates users by their session objects, each user has his own session data.
Note: Although session objects are physically maintained on the ASP server, and not on the client, the essential ID that identifies each user session and differentiates from other possible concurrent sessions is kept in user's cookie. This means if the user's browser does not accept cookies, it also cannot use ASP sessions! You should also know that Session IDs are not guaranteed to be always different.
When the browser window is closed by remote user, the session does not end, simply because there is no way in stateless world of HTTP to inform the ASP server that it should delete the instantiated session object. For closing an ASP session object either the <%Session.abandon%< command must be issued from ASP application, or the session is automatically cancelled after certain period of user inactivity, when the user does not visit any page within that Web application. The inactivity timeout is by default set to twenty minutes and can be changed.
Figure 1 below presents how data can be processed in the typical ASP application. Please notice that as application programmers we now have the chance to process data both locally, using client-side scripting code, and also on the server, using server-side scripting code. Furthermore, local HTML code and local scripting code can either be part of an existing ASP code or can be interactively created and sent to the client side from an ASP script, depending on the various conditions.
All these possibilities significantly enhance our chances to write clever and efficient Web applications.
How data is processed in the typical ASP application.
Who Am I?
We again start with simple ASP code which does nothing but retrieve from the local NW client (installed on the ASP server) our current status when using our NWDir control in the ASP session. Here is the ASP code:
<%@ LANGUAGE="VBSCRIPT" %> <!-- FILE: whoami.asp --> <HTML> <HEAD> <TITLE>WhoAmI ASP sample code </TITLE> </HEAD> <BODY BGCOLOR=#66CDAA> <p> <Font face="Arial" size="+1" color="Red"> WhoAmI? ASP sample code </Font> <p> <% set NWDir1=server.CreateObject("NWDirLib.NWDirCtrl.1") NWDir1.Fullname="NDS:\\DUS-LAB-DEVSUP" response.write "You are:<BR>" + NWDir1.LoginName & "<BR>" set NWDir1=Nothing %> </BODY> </HTML>
This is the entire block of code that should be saved on an ASP Web server in a file with extension .ASP in order to be processed properly by ASP.DLL.
Our code starts with the following line:
<%@ LANGUAGE="VBSCRIPT" %>
This is the first (obligatory) line in ASP code, which says that the scripting language used in the following code is VBScript. Well, VBScript is default for ASP, so in fact I added this line to the code more for learning purposes.
The only important part of this sample code is here:
<% set NWDir1=server.CreateObject("NWDirLib.NWDirCtrl.1") NWDir1.Fullname="NDS:\\DUS-LAB-DEVSUP" response.write "You are:<BR>" + NWDir1.LoginName & "<BR>" set NWDir1=Nothing %>
This whole block is in <% %< brackets which means it will be first processed on the ASP server and the results/outputs of this block (if there are any) will be added between paired <BODY< tags, simply put in the place where this ASP block lies in our ASP source.
First in this snippet we create an instance of our NWDir control by issuing:
We have already learned that there are two ways to create/instantiate an object into HTML code. Similarly, here in ASP we also have two possibilities of how to create objects in ASP code: either using the Server.CreateObject() method, which is pretty similar to generic VB CreateObject() function call, or using the <OBJECT< tag. Here is how the code would look in the latter case:
<OBJECT RUNAT=Server SCOPE=Session ID=NWDir1 CLASSID="CLSID:4F021AE3-9E98-11D0-A808-00C04FDCD94A"> </OBJECT>
Parameter RUNAT=Server says that object should be created on the ASP Web server. Parameter SCOPE=Session specifies the scope for the created instance. The scope can be Session, Application, or Page.
Next we have to initialize NWDir1.FullName property in order to get any valid information from our control. I hardcoded here for simplicity the name of an existing DS tree, which was in my case DUS-LAB-DEVSUP:
Using Response.write() method of a built-in ASP Response object we generate a string that is added into the final HTML document:
response.write "You are:<BR>" + NWDir1.LoginName & "<BR>"
Finally we are supposed to do some cleaning:
The HTML file generated by ASP.DLL from our ASP code is then sent to the client. Figure 2 below shows how our sample looks in the client browser window:
How the sample looks in the client browser window.
Right clicking on the browser window and ViewSource menu, we can see the final HTML code generated from our whoami.asp file:
<!-- FILE: whoami.asp --> <HTML> <HEAD> <TITLE>WhoAmI ASP sample code </TITLE> </HEAD> <BODY BGCOLOR=#66CDAA> <p> <Font face="Arial" size="+1" color="Red"> WhoAmI? ASP sample code </Font> <p> You are:<BR>NDS:\\DUS-LAB-DEVSUP\[Public]<BR> </BODY> </HTML>
As you can see, our ASP call to NWDir component generated following HTML line:
The tree name seems to be OK. But why [Public]? Why has the user of this simple ASP application been recognized as a [Public]? We should know that [Public] is a special type of object, a special trustee, which is by default granted some limited rights to the DS tree (Browse). Every DS object that initially connects to the NDS, prior login and authentication takes place, is granted these [Public] rights. This important concept basically allows initial orientation and browsing in the DS tree, and this way it supports the correct login process.
Our NWDir object was created in the security context of the ASP engine service on the Web server because it was this service that instantiated and manipulated our control. Naturally, from the DS tree point of view, this is an unknown object, which is simply granted [Public] rights, and is also recognized by internal DS functions simply as a [Public]. That's why.
Well, you might ask: what will happen in the situation that there is a local user already logged into the DS tree on that PC which serves as our ASP server? This local user can be, for example, the system administrator doing his daily administrative job. Do I, as a remote user, and accessing the server via HTML browser and ASP code, get his rights, when instantiating NWDir control? Remember -we have already shown (in Part 1 of this series) that NWDir control communicates through the NW client, which must be installed on the IIS/ASP machine.
The answer in this case is no-fortunately. When the NWDir control is embedded from the ASP code, it is fully handled by the Web server (and ASP engine) as a service under a certain NT account. The default local user, connected to the DS tree via NW client, uses another, different NT account. And NW client, when handling internal connection tables, creates differences based on security context of used NT accounts. Because a local user uses a security context different from the security context of the ASP engine, he also has his own connection table to the NDS, which is strictly separated from the connection table used for the ASP engine. We will discuss this issue again in more detail later.
Our first sample does not require any special Microsoft HTML extensions on the browser side; it can be viewed not only by IE, for example, but also by Netscape. The result is shown in Figure 3, which is pretty much the same as the result displayed by IE.
The sample as viewed by Netscape.
Listing the NDS Tree in ASP
WhoAmI in ASP was an easy sample code, a kind of "starter" code from our menu. Our next sample will be a bit more complicated, presenting how the NDS tree can be traversed from the root down to the branches and how the hierarchical structure of the tree can be retrieved and displayed in the browser window. This time we start the discussion by displaying the demanding result in Figure 4.
In case it is not fully clear to you from the Figure 4, the hierarchy among objects is simply presented here by moving object names by the certain offset to the right side of the browser window.
Traversing the NDS tree.
As you can see, it cannot be recommended to run this sample against a huge NDS tree with thousands of object. First, it may take quite a long time for the ASP server to finish and return with the HTML document; and second, the resulting HTML document could be long and thus quite difficult to handle on both the ASP server side and the client browser side.
Let us start with the code headers:
<%@ LANGUAGE="VBSCRIPT" %> <!-- FILE: listTree.asp --> <HTML> <TITLE> List DS tree ASP sample code </TITLE> </HEAD>
What follows is the code that on the server side declares one variable totalObjects (with page scope validity) and then instantiates the NWDir control using Server.CreateObject() method. Variable totalObjects is used in the application as a simple counter of traversed objects:
<% Public totalObjects Set NWDir1=Server.CreateObject("NWDirLib.NWDirCtrl.1") %>
Walking down the whole tree from the root and retrieving all existing objects is usually most efficiently done when using some kind of recursive algorithm applied on the object lying on the top of the tree hierarchy.
This approach is used in this sample code; our recursive procedure is called Read- Container(), and requires two parameters: a context and a level. Here is our code:
<SCRIPT LANGUAGE="VBScript" RUNAT="Server"> Sub ReadContainer(context,level) Dim entry, output, newContext, name On Error Resume Next NWDir1.FullName=context For each entry in NWDir1.entries If err.number Then err.number=0 Exit For End If name="<BR>" For i=0 to level name=name+" " Next name=name+"<B><FONT COLOR=blue>"+entry.ShortName+"</B></FONT>" response.write(name) name=" (" + entry.Layout.Name + ") " response.write(name) If entry.Layout.Container=TRUE then newContext=context+"\"+entry.ShortName call ReadContainer(newContext ,level+1) End If totalObjects = totalObjects +1 Next End Sub
First, notice the line this block starts with:
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
This is how a <SCRIPT< tag should be used in ASP on the server side. Parameter RUNAT=Server says that the following script should be run on the server and not on the client. Writing scripting ASP code this way we do not need to use <% and %< delimiters.
Procedure ReadContainer() requires two parameters: context and level. Parameter context holds the full name of the container object to be listed, in following (UNC-like) format:
Parameter level is used to track down the recursion level and to create the required hierarchy when objects are displayed in the browser window.The following code snippet checks for container, and if that condition is met, the new full name of the container object is created and the procedure ReadContainer() is called recursively:
If entry.Layout.Container=TRUE then newContext=context+"\"+entry.ShortName call ReadContainer(newContext ,level+1) End If
The following procedure ListDSTree() is our starting point. It initializes NWDir control, sets the starting parameters, and calls ReadContainer() for the first time:
Sub ListDSTree(treeName) Dim retcode, fullName, level NWDir1.FullName = NWDir1.FullNameFromTreeAndContext(treeName,"[Root]") fullName=NWDir1.LoginName response.write "<I>(Listing the whole DS tree structure may take some time !)</I><p>" response.write "<U><B>" & treeName & "</B></U> " totalObjects=1 call ReadContainer("NDS:\\"+treeName,1) response.write "<BR><BR>Total objects found: " & totalObjects End Sub </SCRIPT>
Here is the rest of our program. Putting ListDSTree() procedure here makes sure that the output HTML code from the DS tree walking will be put correctly between paired <BODY< tags, exactly as we want it:
<BODY BGCOLOR=#66CDAA> <p> <FONT FACE="Arial" SIZE="+1" COLOR="Red"> List DS tree ASP sample code </FONT> <p> <% ListDSTree("DUS-LAB-DEV-51T") %> </BODY> </HTML>
Results of this ASP code can also be displayed when using Netscape.
Part 4 will discuss verifying remote users against NDS with the help of ASP.
* Originally published in Novell AppNotes
The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.