Back in the day we kept phone number in a dataset which we’d browse with ISPF and find the number we needed. Then we improved it a bit with an ISPF BRIF service program that filtered the lines of the dataset based upon an input search parameter saving the “FIND” step. At first we maintained the dataset manually, then someone found a way to get a weekly feed from the payroll or HR system to keep it up to date.
Alas, then it was all taken away from us. All of this directory information was moved to Active Directory or something, we lost the weekly feed and we have to go through several steps to look up a phone number using Outlook or whatever. We lost our subsecond response times, that’s for sure.
After living with this for awhile, I searched for a way to access the directory information from TSO. And there is a way with ldapsearch a.k.a. GLDSRCH. ldapsearch is currently documented in IBM Tivoli Directory Server Client Programming for z/OS and the information on running under TSO is here. The fact the this is the same as GLDSRCH which is (now) in the linklist, is not well documented but you can see this in SGLDEXEC(LDAPSRCH).
You’ll need to know the hostname or IP address and the port to access your directory and whether you need to provide credentials to log into it or use kerberos. (Let’s hope not.) In my case, the directory is not secured from reading.
I would also use and have used an ldap browser such as the one from Softerra to figure the base dn (distinguished name) and the attributes your company’s directory has that you want to show. Using a reasonable base dn will improve performance by narrowing the searching down the appropriate tree of the ldap directory.
The ldapsearch filter is not really described in the IBM manual other than referring you to the RFC and with a few examples. But using a proper filter may be necessary to weed out unnecessary results. For example, for one Active Directory system I have used, I needed to filter out Computers from the results,
which selects records with objectclass of person and not objectclass Computer and with a cn (common name) that has the word John in it.
In the GLDSRCH command you specify the filter and the attributes you want to be returned. For example, you might want cn and telephoneNumber and Department. GLDSRCH returns the results like
dn: Distinguished Name (DN)
dn: Distinguished Name (DN)
So a Rexx program could use Interpret to assign values to attribute variables. One wrinkle is that binary data gets encoded in base64. I ran across garbage in one directory that would be returned this way which was a bit confusing at first.
My approach to a phone number lookup utility is to 1) build a search from the input parameter, 2) do the ldap search routing the output to a dataset, 3) read the dataset into a stem variable with EXECIO, 4) parse the results building a new stem variable for each result, 5) browse the resulting stem variable with STEMVIEW, a freeware utility from the CBT Tape. (FILE 183 download), and 6) implement with an ISPF command table entry. Lionel B. Dyke has a project similar to mine, LDAPMAIL, which also does an ldapsearch in Rexx.
Here is and example of the basic guts of calling the LDAP search with a filter and some attributes specified and picking up the results:
/* Rexx */ ldaphost = "directory.mycompany.com" ldapPort = "389" ldapbase = "o=InternalUsers,dc=mycompany,dc=com" filter = "(&(objectClass=Person)(CN=*Quigley*))" ddname = "LDAP" || Random(9999) "ALLOCATE FILE("ddname") UNIT(VIO) SPACE(1 1) CYL" 'GLDSRCH /-L -h' ldapHost '-p' ldapPort '-s sub', '-b' ldapbase, '"'filter'" 2>&1 >//DD:'ddname, 'uid', 'cn', 'telephoneNumber', 'title', 'department', 'companyname', 'mail', 'l' "EXECIO * DISKR" ddname "(STEM LDAP. FINIS" "FREE FILE("ddname")" Do i = 1 to ldap.0 Say ldap.i End
Some of these attributes are, no doubt, unique to this directory, as should be the ldapbase value. The output from running this looks something like this:
dn: uid=xx0886,o=InternalUsers,dc=MyCompany,dc=com l: SPF mail: Abigale.M.Quigley@MyCompany.com cn: Abigale M Quigley uid: xx0886 dn: uid=yyopy4,o=InternalUsers,dc=MyCompany,dc=com l: SPF mail: Lola.Quigley@MyCompany.com companyname: MYCOMPANY SECURI department: SPRNGFLD LD PROCESSING title: LOSS DRAFTS TEAM LEAD telephoneNumber: (555)555-3224 ext. 43224 cn: Lola Quigley uid: yyopy4 dn: uid=zzooap,o=InternalUsers,dc=MyCompany,dc=com l: BRE mail: Melissa.Quigley@MyCompany.com companyname: MYCOMPANY SECURI department: CITIMORTGAGE title: CUSTOMER CARE SPECIALIST telephoneNumber: 555-555-8460 ext. 24625 cn: Melissa Quigley uid: zzooap
Note that not all attributes exist for each directory entry found. Play around with different filters and see what you get. Occasionally I would get attributes that look like this:
which happens when there is non-printable characters in the value. This example is a base64 encoded value of the ASCII string “(555)555-4031 ext. Â”. Somehow, some garbage characters got into the phone number.
This is what I ended up with: phone.rexx.