The Novell Controls for ActiveX and Visual Basic: Reading and Writing NDS Stream Fields
Articles and Tips: article
Software Engineer
Novell DeveloperNet University
madair@novell.com
01 Mar 2000
This article is the seventh installment in a series on Novell Directory Services (NDS) programming, using the Novell Controls for ActiveX and Visual Basic. So far, we've talked about setting up your development environment, logging in to a directory, reading and searching NDS field values, writing data values to NDS fields, and creating directory entries. This article tells how to read and write stream field values.
Catching Up
If you're jumping into the middle of this series of articles, you may need to review a few NDS concepts and programming techniques. For a quick review of the structures that comprise the NDS directory: fields, entries, and layouts, see "The Novell Controls for ActiveX and Visual Basic: Searching NDS Field Values," in Novell Developer Notes, October 1999, which is on the DeveloperNet Web site, http://developer.novell.com/research/devnotes.htm.
You may also want to review the articles on reading and writing NDS field values, in the September and December 1999 issues of Novell Developer Notes, respectively.
The example program in this article is a slight modification of the CreateEntry program we developed in the last article, "The Novell Controls for ActiveX and Visual Basic: Creating Directory Entries," in the January 2000 issue.
Streams
Streams are binary data with no prescribed syntax. Stream attributes are usually used to store large data objects, like login scripts or images. There are applications that use streams to store pictures of users, fingerprint and retinal scan images, and application passwords to implement single-sign-on security.
As mentioned in previous articles, your programs use the Novell Directory Control's GetFieldValue and SetFieldValue methods to read and write data in the fields of directory entries. Stream fields are an exception; the Directory Control has separate methods for reading and writing stream data. SaveFieldValueToFile reads data out of a stream field and saves it to a file. LoadFieldValueFromFile copies data from a file to a stream field in a directory entry. After calling LoadFieldValueFromFile, your program must call the entry's Update method to make changes to the field permanent, or the Abort method to discard changes.
Example Program: StreamExample
StreamExample is a simple modification of the CreateEntry program in the previous article, with an added feature that it can add a login script when creating a user entry. As with CreateEntry, StreamExample creates organization, organizational unit, and user entries, based on specifications given in a text file. StreamExample looks for one additional field in user entries--the name of a file containing the user's login script.
Examples of organization, organizational unit, and user specifications are shown below.
ORGANIZATION~VerySmallCompany OU~VerySmallCompany\Marketing OU~VerySmallCompany\Engineering OU~VerySmallCompany\Accounting USER~VerySmallCompany\George Smith~Smith~President~555-1212~LoginScript.txt USER~VerySmallCompany\Veronica Smith~Smith~VP Mktg~555-6318~LoginScript.txt USER~VerySmallCompany\Jedd Smith~Smith~VP Eng~555-6051~LoginScript.txt USER~VerySmallCompany\Samuel Smith~Smith~VP Acct~555-3694~LoginScript.txt USER~VerySmallCompany\Emma Jones~Jones~Pres Sec~555-3056~LoginScript.txt
When StreamExample is executed, it allows the user to specify which directory the program is to operate on. The user can either select a directory to which the client is already logged in to, or log in to another directory. After the directory is specified, StreamExample allows the user to select the file that contains specifications of the directory entries to be created. Figure 1 shows StreamExample's user interface.
To build the StreamExample program:
Start Visual Basic and create a new "Standard EXE" project.
Add the Novell Directory and Session controls and the Microsoft Common Dialog Control to your project:
Open the Components dialog by selecting "Components" from the Project menu, or by right-clicking the Toolbox and selecting "Components" from the pop-up menu.
Scroll down the list of components and check the boxes next to "Novell Directory Control," "Novell Session Control," and "Microsoft Common Dialog Control 6.0."
Click "OK."
StreamExample consists of 3 forms and one code module. As mentioned previously, the program is just a slight modification of the CreateEntry program.
Figure 1: StreamExampleuser interface.
ConnectionsForm, LoginForm, and Module1
The previous article in this series, "The Novell Controls for ActiveX and Visual Basic: Creating Directory Entries" (January 2000), had instructions for designing and writing the associated code for three forms, ConnectionsForm, LoginForm, and CreateEntryForm and one code module, Module1. Create a new directory for the SearchField program and copy ConnectionsForm.frm, LoginForm.frm, CreateEntryForm.frm, and Module1.bas to this new directory.
After copying the files, do the following:
Add Module1 to the project by selecting "Add Module" from the Project menu, clicking on the "Existing" tab, and selecting the Module1.bas file that you just copied.
Add the forms to the project by selecting "Add Form" from the Project menu, clicking on the "Existing" tab, and selecting the ConnectionsForm.frm, LoginForm.frm, and CreateEntryForm.frm files that you just copied.
Make ConnectionsForm the project's startup form by opening the project's property sheet from the Project menu, then selecting "ConnectionsForm" from the Startup Object drop-down menu.
CreateEntryForm
CreateEntryForm contains the procedures that parse the file of directory entry specifications and create the appropriate organization, organizational unit, and user entries. You will need to add or change just a few lines in the ParseScriptFile procedure. Those lines are shown in bold in the code fragment below.
'is it a User? ElseIf Left$(lineStr, 5) = "USER~" Then 'copy to temporary string, strip off USER~ tempStr = Right$(lineStr, Len(lineStr) - 5) 'copy name to nameStr, then strip it off nameStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare)) tempStr = Right$(tempStr, Len(tempStr) - Len(nameStr)) nameStr = Left$(nameStr, Len(nameStr) - 1) 'copy surname to surnameStr, then strip it off surnameStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare)) tempStr = Right$(tempStr, Len(tempStr) - Len(surnameStr)) surnameStr = Left$(surnameStr, Len(surnameStr) - 1) 'copy title to titleStr, then strip it off titleStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare)) tempStr = Right$(tempStr, Len(tempStr) - Len(titleStr)) titleStr = Left$(titleStr, Len(titleStr) - 1) 'copy phone to phoneStr, then strip it off phoneStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare)) tempStr = Right$(tempStr, Len(tempStr) - Len(phoneStr)) phoneStr = Left$(phoneStr, Len(phoneStr) - 1) 'loginScript is everything left, copy it to loginScriptStr loginScriptStr = tempStr If CreateDeleteOpt(0).Value Then DisplayLine ("Creating User: " + nameStr) If (CreateUser(nameStr, surnameStr, titleStr, phoneStr, _ loginScriptStr) = False) Then DisplayLine ("*** Error creating user. Script file line:") DisplayLine (lineStr) End If Else On Error GoTo DeleteError DisplayLine ("Deleting User: " + nameStr) NWDir1.Entries.Remove (nameStr) End If
You will also need to modify the CreateUser procedure to handle login script files. Again, the modifications to the procedure are shown in bold.
Private Function CreateUser(name As String, surname As String, _ title As String, phone As String, loginScriptFile As String) As Boolean Dim newEntry As NWEntry On Error GoTo AddError Set newEntry = NWDir1.Entries.Add("User", name) 'set attributes for the new User If (newEntry.SetFieldValue("Surname", surname) = True) And _ (newEntry.SetFieldValue("Title", title) = True) And _ (newEntry.SetFieldValue("Telephone Number", phone) = True) And _ (newEntry.LoadFieldValueFromFile("Login Script", loginScriptFile) _ = True) Then DisplayLine (" Surname = " + surname) DisplayLine (" Title = " + title) DisplayLine (" Phone = " + phone) DisplayLine (" Login Script File = " + loginScriptFile) newEntry.Update CreateUser = True Else newEntry.Abort CreateUser = False End If Exit Function AddError: newEntry.Abort CreateUser = False End Function
One More Time
The next article in this series will show how to add new layouts to the NDS directory, a process known as "extending the directory schema."
* 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.