This document describes the Iceberg Name Mapping Service, its implementation, and usage.
About the name mapping service
In Iceberg, a user could have several end-points through which she can be reached. These end-points could be devices (e.g., cell-phone, pager, etc.) or they could be communication services (e.g., Short Message Service, Instant message service, Email service, etc.). The ids associated with each of these end-points is known as the service-specific-id. For instance, a telephone number, or a pager number is a service-specific-id.
A user is also assigned a unique-id to for unique identification. The Name Mapping Service (NMS) serves the purpose of mapping a service-specific-id to the user's unique-id. Such a mapping is required since one may not always have the user's unique-id for identification. For instance, imagine a user calling another by dialing a phone-number (a service-specific-id).
The name mapping service also serves the purpose of locating the user's iPOP. Given a user's unique-id, the name mapping service can return the required location. This is similar to the DNS returning an MX record with the user's mail server.
Although the above discussion is in the context of users, any service or entity that is reachable can also have service-specific-ids and unique-ids. For instance, one may call a voice-mail service by dialing a phone number (a service-specific-id).
The name-space hierarchy
The Iceberg name mapping service has a hierarchy similar to LDAP/X.500 naming tree. Each node in the tree is a type-value pair. However, we do not use the LDAP/X.500 tree schema itself. We define our own. However, we use the same distribution and referral mechanisms as in LDAP (similar to DNS as well). In our tree, only the leaves have relevant information.
In Iceberg, there could be several name-spaces corresponding to different devices and services. For instance, phone numbers could form a hierarchy, cell-phome IMSI numbers could form one, pager numbers could form one, IP host-names, e-mail addresses, etc. To handle these multiple hierarchies, we define a top-level root-node with a "type=<typename>" identification. The hierarchy within each type could be defined independently.
There are currently three name-spaces defined: one for cell-phone numbers, one for IP host-names, and one for Iceberg unique-ids. We have chosen to represent unique-ids as email addresses of users (this email address could be a dummy one; need not be the actual email address; the syntax is what is relevant).
With the defined hierarchy for these three name-spaces, the following are examples of LDAP DN (Distinguished Names) in our tree:
Cell-Phone Numbers: cpnum=<3-digit-number>, type=mygsm Example: cpnum=107, type=mygsm (In our testbed, cell-phone numbers are from a flat space of 3-digit numbers) IP host names: host=<host-name>, l3=<level3-name>, l2=<level2-name>, l1=<level1-name>, type=ipaddr Example: host=jake, l3=cs, l2=berkeley, l1=edu, type=ipaddr The name starts with l1 at the topmost level and can extend to any number of levels down the hierarchy. Example: host=dummy, l2=example, l1=com, type=ipaddr Unique-Ids: uid=<user-id>, l3=<level3-name>, l2=<level2-name>, l1=<level1-name>, type=uniq Example: uid=bhaskar, l3=cs, l2=berkeley, l1=edu, type=uniq
Look at the files cpnums, ipaddrs, and uniqs for more examples.
Since Iceberg unique-ids are equivalent to email addresses, they have two equivalent representations: email-ids and LDAP DNs. Both of these are used in different places in the code.
The server and the client
We use the OpenLDAP open-source LDAP server for our implementation. This implementation allows us to define our own LDAP tree schema. However, it does not have arbitrary referrals from any point in the tree. We use this implementation in a stand-alone fashion.
We do not use the full LDAP search features since this is not required of the name mapping service. We only need a mechanism to return the information at a node given the DN (Distinguished Name). Hence the client of the LDAP server does a search in this very restricted manner. For the Java-based LDAP client, we use Netscape's Directory SDK 3.0 (look here).
The client API is implemented in ldap.java in the myutil package.
Configuring and running the service
The server is run as the daemon slapd (no command-line argument necessary). The source compiles easily on FreeBSD and Linux (I have tried on these). The location of the configuration files is usually /etc/openldap/ but could be different depending on how you installed it. See man slapd.conf for the default location of the configuration files.
The relevant configuration files are slapd.oc.conf and slapd.conf. The first one gives the object class definitions and is included by the second. If you look in slapd.conf here, you will see lines starting with "directory" specifying the directories where the naming information will be stored. Replace these with whatever directories you want and create those directories as well. Also, you could change the "suffix" and "rootdn" fields for "type=ipaddr" and "type=uniq" to reflect your domain of operation.
Client operations for administering
The OpenLDAP package also comes with command-line LDAP clients for common operations. The relevant commands for us are ldapadd and ldapdelete. Although the man pages for these provide enough information, not all of it is relevant. Hence a quick summary of how you can use these is below.
The files cpnums, ipaddrs, and uniqs give the nodes to be added to the tree. Note that each of the files have the top-level nodes before the leaves. That is, the top-level nodes are to be created before the leaves can be attached to them.
The cpnums and ipaddrs files correspond to service-specific-ids. Hence each of the leaf-entry in them point to the unique-id corresponding to that service-specific-id. This is via the "aliasedObjectName" field.
In the case of uniqs, the relevant field is the "iPOPUrl" field that gives the location (and class-name) of the iPOP service corresponding to the user.
Format of configuration files
The configuration files cpnums, ipaddrs, and uniqs are in LDIF format (LDAP Directory Interchange Format). Each entry gives the LDAP Distinguished Name (DN) and then each of the attributes. The first entry in the tree gives the root node in the tree. Then the children are given.
For the service-specific-id entries "cpnums" and "ipaddrs", the two attibutes are: aliasedObjectName and objectClass. The aliasedObjectName is the DN of the unique-id entry. The objectClass field is always "alias" (see the example files cpnums and ipaddrs as you read this).
For the unique-id entries, the three attributes are: uid (this is simply the uid field from the DN), objectClass (this is always "uidobj"), and iPOPUrl. The last field has the format:
iPOPUrl: <iPOP-Host>[:<iSpace-port>]/<iPOP service className>
The host is the machine where the iPOP is run. The port is the "iSpace.port" property value in your Ninja configuration file (defaults to 1099). The iPOP service class name is "iceberg.ipop.CAD" in this release.
Edit the configuration files to match your configuration. To load these to the LDAP server, issue the command:
ldapadd -h slapd-host -c -f file-name -D DN-base -w secret
The "-h slapd-host" specifies the slapd server machine; the "-f file-name" specifies the file from which to read the entries; the "-D DN-base" specifies the DN of the base of the tree to which the entries belong. The "-w secret" specifies the password to be used (see the same in slapd.conf as well). The "-c" specifies that the command should continue as much as possible even if there is an error. This is useful since the addition of an already existing entry is considered an error.
ldapadd -h jake.cs.berkeley.edu -c -f cpnums -D "type=gsm" -w secret ldapadd -h jake.cs.berkeley.edu -c -f ipaddrs -D "l3=cs, l2=berkeley, l1=edu, type=ipaddr" -w secret ldapadd -h jake.cs.berkeley.edu -c -f uniqs -D "l3=cs, l2=berkeley, l1=edu, type=uniq" -w secret
To delete an entry, use:
ldapdelete -h slapd-host -D DN-base -w secret <DN-to-delete>
ldapdelete -h jake.cs.berkeley.edu -D "type=gsm" -w secret "cpnum=110, type=gsm" ldapdelete -h jake.cs.berkeley.edu -D "l3=cs, l2=berkeley, l1=edu, type=ipaddr" \ -w secret "host=narmada, l3=cs, l2=berkeley, l1=edu, type=ipaddr" ldapdelete -h jake.cs.berkeley.edu -D "l3=cs, l2=berkeley, l1=edu, type=uniq" \ -w secret "uid=bhaskar, l3=cs, l2=berkeley, l1=edu, type=uniq"
To modify an entry, I usually delete the entry, modify it in the one of the three files mentioned above, and issue the corresponding "ldapadd" command.