Novell is now a part of Micro Focus

The NetWare API: Making Your Programs NDS-Aware

Articles and Tips: article

MORGAN B. ADAIR
Senior Research Engineer
Systems Research Department

01 Jul 1995


Although it is expected that most NetWare installations will eventually move to NetWare Directory Services (NDS), bindery-based versions of NetWare (2.x and 3.x) will be around for a long time. Before your programs can take advantage of NDS services, your programs need to know if they are running in a bindery or NDS environment. This DevNote shows one simple way your programs can distinguish between connections to bindery-based NetWare servers and NDS connections.

Previous DevNotes in This Series May/June 95 "The NetWare API: Verifying the Presence of Network Resources"

Introduction

In the May/June '95 issue of Novell Developer Notes, in "The NetWare API: Verifying the Presence of Network Resources," I discussed how a DOS program can verify whether certain network resources are available: IPX, NetBIOS, and the NetWare shell (NETX) or DOS requester (VLM). In this installment of "The NetWare API," I continue this thread a little further. Once your program knows that it is running in a NetWare environment (and possibly what communications protocols are in use), it may need to know whether NetWare Directory Services (NDS) is available.

What do you get by writing your program to be NDS-aware?

  • access to objects and attributes of the NetWare Directory,

  • the ability to extend the Directory by adding attributes or creating new object types,

  • the ability to manage NDS, including NDS partition management and event auditing.

Bindery Emulation

Bindery emulation is a feature of NDS that makes it possible for programs that access the bindery to continue to work under NDS. Network administrators must enable bindery emulation by setting a bindery context for the file server. The bindery context is a parameter the administrator sets at the file server console. It is usually set when the administrator installs NetWare 4 on the server, but can be set or changed at any time. Under bindery emulation, an NDS container is treated as a bindery. Calls to the bindery function NWScanObject return objects that have been created in the container.

If your program is written to access the bindery, your program will continue to work under NDS, if bindery emulation has been enabled on the file servers on which your program is run.

For new software you are developing, however, you should write programs to determine whether they are running in a bindery or NDS environment, and make the appropriate function calls.

Connection Types

Whether your program is running in a bindery or NDS environment is determined by the connection type the client workstation has to the network. Determining the NetWare version running on a file server is not sufficient to determine whether the workstation is running in bindery or NDS mode. If a network has more than one Directory tree, then workstations on the network can log into one tree under NDS, and have bindery connections to specific file servers in another tree.

You will probably find some confusion in the terms used to refer to various types of connections. The confusion primarily exists because NetWare 2 and 3 had utilities called ATTACH and LOGIN. Both utilities logged a workstation in to a file server, but LOGIN also executed the user's login script. On NetWare 4, you log in to a server without executing the login script by running LOGIN with the /NS command line option.

A workstation forms its first file server connection when you run VLM or NETX. The workstation sends out a Service Advertising Protocol (SAP) request to locate the nearest NetWare file server. When a server responds, the workstation has a connection to the file server that appears as "NOT-LOGGED-IN" on the file server console. The workstation is said to be "attached" to the file server. If the NET.CFG file specifies a preferred file server, the workstation establishes a bindery connection; if it specifies a preferred tree, the workstation establishes an NDS connection.

The workstation uses the Routing Information Protocol (RIP) to communicate with the attached file server to locate the preferred file server or a file server in the preferred tree. In the process, the workstation may attach to other file servers. A workstation may form several file server connections before the user even logs in to the network.

Every connection can be categorized as bindery or NDS connections. There are two types of bindery connections:

  • Attached. Established by SAP or RIP, or by the NWAttachToFileServer function. Provides access to the file server's routing tables and the SYS:LOGIN directory.

  • Logged-in. Established by the NWLoginToFileServer function. Provides access to the server's file system and other resources (like print queues), depending on bindery and file system access rights.

There are three types of NDS connections:

  • Attached. Established by SAP or RIP, or by the NWAttachToFileServer function. Provides access to the file server's routing tables and the SYS:LOGIN directory.

  • Logged-in. Established by the NWDSLogin function. Provides access the NDS directory.

  • Authenticated. Established by the NWDSAuthenticate function. Provides access to the server's file system and other resources (like print queues), depending on NDS and file system access rights.

In addition, you may encounter four other terms referring to file server connections.

  • Monitored Connection. An NDS connection to the file server that contains a writablereplica of the NDS partition that contains the object you are logged in as. When logging out, you should log out of the monitored connection last. Use the NWDSGetMonitoredConnection function to determine which connection is the monitored connection.

  • Default Connection. The file server connection associated with the default drive. Or if the default drive is a local drive, the default connection is the primary connection (see below). If there is no primary connection, the default connection is the first connection in the worksation's connection table. Use the NWGetDefaultConnectionID function to determine which connection is the default connection.

  • Primary Connection. The connection to the file server from which the login script was read. You can determine which connection is the primary connection either by calling the NWGetPrimaryConnectionID function, or by calling NWGetConnectionStatus, and test the value returned in the connectFlags parameter with CONNECTION_PRIMARY.

  • Preferred Connection. If the NET.CFG file specified a preferred tree, the preferred connection is the first file server in the preferred tree to respond the workstation's SAP or RIP request. If the NET.CFG file specified a preferred file server, the preferred connection is the connection to that server. Use the NWGetPreferredConnName function to determine which connection is the preferred connection.

Example Program: CONNTYPE.C

This program uses the NWGetConnectionList function to determine which file servers the workstation is connected to. Then, for each connection, the program calls NWDSGetConnectionInfo to determine whether the connection is a bindery or NDS connection, and whether the connection is attached, logged-in, or authenticated. The program also calls NWGetPreferredConnName to get the name of the preferred connection (NDS tree or file server).

Note how CONNTYPE tests the value of the connType parameter returned by NWDSGetConnectionType. The documentation in the Client SDK does not clearly state that you determine what type of connection you have by testing which of the three low-order bits in this value are set.

#include <stdio.h<<
#include <stdlib.h<<
#include <string.h<<
#include <nwcalls.h<<
#include <nwnet.h<<
#define MAX_SERVER_NAME_LEN  48

void main ()

{

NWCCODE         ccode;

NWNUMBER        maxConnections, numActiveConnections;

NWCONN_HANDLE   *connListBuffer;

NWCONN_TYPE     connType;

BYTE            preferredType;

/* since I'm using i to index into a list of

  conn handles it needs to be conn handle size */

NWCONN_HANDLE   i;

BYTE                connectedServerName[MAX_SERVER_NAME_LEN+1];

BYTE                preferredName[MAX_TREE_NAME_CHARS+1];

ccode = NWCallsInit(NULL, NULL);

if (ccode) {

  printf("NWCallsInit failed\n");

  exit(1);

}

/* maxConnections should be either the SESSIONS value in net.cfg,

  or 9 which is default if SESSIONS not set*/

NWGetMaximumConnections(&maxConnections);&
connListBuffer=malloc(maxConnections * sizeof(NWCONN_HANDLE));

ccode=NWGetConnectionList(0,

                        connListBuffer,

                        maxConnections,

                        &numActiveConnections);&
if(ccode) {

  printf("NWGetConnectionList failed, ccode = %X\n", ccode);

  exit(1);

} else {

  for(i=0;i<numActiveConnections;i++) {<
     /* Here's the function that gets the information we're

           interested in.  Pass in NULLs for the parameters

       that we don't care about */

     ccode = NWDSGetConnectionInfo( connListBuffer[i],

                                         NULL,

                                         &connType,&
                                         NULL,

                                         connectedServerName,

                                         NULL,

                                         NULL,

                                         NULL,

                                         NULL,

                                         NULL);

if(ccode) {

  printf("NWDSGetConnectionInfo failed, ccode = %X", ccode);

  break;

}

printf("Server %s\n", connectedServerName);

if (connType & 0x0001)

  printf("\tNDS connection\n");

else

  printf("\tBindery connection\n");

if (connType & 0x0002)

  printf("\tLogged in connection\n");

if (connType & 0x0004)

  printf("\tAuthenticated connection\n");

}

}

ccode=NWGetPreferredConnName(preferredName,

                            &preferredType);&
if (ccode) {

  printf("NWGetPreferredConnName failed, ccode = %X\n", ccode);

  exit(1);

} else {

  if (preferredType == NWNDS_CONNECTION)

     printf("Preferred tree = %s\n", preferredName);

  else

     printf("Preferred server = %s\n", preferredName);

}

free(connListBuffer);

}

* Originally published in Novell AppNotes


Disclaimer

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.

© Copyright Micro Focus or one of its affiliates