Integrating Cisco Unified Communications Manager version 7 with eDirectory

0 Likes
over 12 years ago
By: Andy Swiffin

Contents:









Abstract



Cisco Unified Communications Manager (Unified CM) version 7 is now the third major release since Cisco changed to the appliance model based on Linux. Unified CM version 5 ushered in many changes not least being a move away from its own internal directory with the option to synchronize user information from the customers own "corporate directory " via LDAP. Unified CM 7 has not significantly changed the way that this LDAP synchronization operates and this AppNote intends to show that, as with Unified CM 6, it is a well behaved LDAP client and it will synchronize quite happily from Novell eDirectory (which is a well behaved LDAP server). I hope that Cisco customers desiring this integration will approach Cisco to ask for eDirectory to be added to the list of supported directories.




Introduction



This is now a third AppNote on the theme of integrating Cisco Unified CM with Novell eDirectory. Unified CM 7 does not look significantly different from the two previous "appliance" style, Linux hosted versions and as a migration to version 7 was planned at Dundee university it was hoped that there would not be any significant change in the way LDAP operated compared to versions 5 and 6. This was found to be the case and although there have been some minor changes to the LDAP integration since version 6 these are generally for the better. You can read about my previous experiments in integrating 5 and 6 here [1] and the forerunner to that, the very different windows based CCM 4 here [2]. The recurring theme in my two prior publications has been to show that in fact the integration with eDirectory works very well indeed, and that there is no real reason why Cisco should not add eDirectory to their supported list. Without further ado, let us look at how the integration performed.

Unified CM 7 and eDirectory



The Unified CM configuration required for this was well covered in [1] and has not changed much so no further screenshots are included here. The process as before requires us to first specify in System->LDAP that we wish to enable LDAP synchronization and which type of directory we will be using, Microsoft AD or Netscape. NB that with Unified CM 7.1.3 OpenLDAP has appeared as an option for directory type [6], although for some time there has been an "Appnote" describing how integration with OpenLDAP may be achieved available here [3] this used the same technique as with eDirectory, i.e. lie to Unified CM that it’s Netscape you’re using.

The choice of directory also involves a choice in the directory naming attribute, normally with Netscape/eDirectory uid will be used but for AD this would be sAMAccountName.

Following on from the choice of directory type – Netscape, (for eDirectory), we can specify the options required for our LDAP search. There are no surprises here for anyone who has configured an LDAP search before, with an FDN and password being required, a search base and the location of the LDAP server. There is little choice in the attributes which will be downloaded either which include givenname, sn, departmentnumber, one of the few which you can control is the email address which normally we would map to "mail".

Having specified a "next search time" in the near future the next stage is to take a wireshark capture of the packets that are exchanged. Version 8.7 of eDirectory had been installed on a Windows 2003 server to best facilitate this.

The first trace is shown below, irrelevant sections of the packets have been removed for clarity.

Initially Unified CM makes two binds to the LDAP server

Frame 19 (115 bytes on wire, 115 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage bindRequest(1) simple
bindRequest
version: 3
name: cn=admin,ou=system,o=dundee
authentication: simple (0)
[Response In: 20]

Frame 20 (80 bytes on wire, 80 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage bindResponse(1)
bindResponse
resultCode: success (0)
[Response To: 19]

Frame 25 (115 bytes on wire, 115 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage bindRequest(1) simple
bindRequest
version: 3
name: cn=admin,ou=system,o=dundee
authentication: simple (0)
[Response In: 26]


Frame 26 (80 bytes on wire, 80 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage bindResponse(1)
bindResponse
resultCode: success (0)
[Response To: 25]



Following on from that a search is initiated with an empty baseObject, in doing this the client is asking the server to provide information about itself.




Frame 28 (105 bytes on wire, 105 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(2) "" baseObject
searchRequest
baseObject:
scope: baseObject (0)
derefAliases: derefAlways (3)
Filter: (objectClass=*)
filter: present (7)
present: objectClass
attributes: 0 items

Frame 29 (1434 bytes on wire, 1434 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(2) ""
searchResEntry
objectName:
attributes: 0 items
Item subschemaSubentry
type: subschemaSubentry
vals: 1 item
cn=schema
Item supportedGroupingTypes
type: supportedGroupingTypes
vals: 1 item
2.16.840.1.113719.1.27.103.7
Item namingContexts
type: namingContexts
vals: 1 item

Item supportedExtension
type: supportedExtension
vals: 0 items
2.16.840.1.113719.1.142.100.1
2.16.840.1.113719.1.142.100.2
2.16.840.1.113719.1.142.100.4
... <many values omitted>
2.16.840.1.113730.3.4.3



The most important part of the result packet is the list of supported ldap extensions and the last one will be familiar to anyone who has read the previous Appnote in this series [1]. This extension specifies that the server supports persistent search as described in [4], the implications of this will be seen soon.



Unified CM then closes one of the two connections



Frame 33 (73 bytes on wire, 73 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage unbindRequest(3)



and then carries on with the remaining connection to perform the actual search




Frame 38 (254 bytes on wire, 254 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(2) "ou=users,o=dundee" wholeSubtree
searchRequest
baseObject: ou=users,o=dundee
scope: wholeSubtree (2)
derefAliases: derefAlways (3)
typesOnly: False
Filter: (objectclass=inetOrgPerson)
filter: equalityMatch (3)
equalityMatch
attributeDesc: objectclass
assertionValue: inetOrgPerson
attributes: 12 items
Item: uid
Item: givenname
Item: initials
Item: sn
Item: manager
Item: departmentnumber
Item: telephonenumber
Item: mail
Item: title
Item: homephone
Item: mobile
Item: pager
[Response In: 39]



And the response to the search request is a packet (or number of packets should there be enough entries) containing the user information.



Frame 39 (1275 bytes on wire, 1275 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(2) "cn=alswiffin,ou=users,o=dundee" [1 result]
searchResEntry
objectName: cn=alswiffin,ou=users,o=dundee
attributes: 6 items
Item departmentnumber
type: departmentnumber
vals: 1 item
ICS
Item mail
type: mail
vals: 1 item
a.l.swiffin@dundee.ac.uk
Item uid
type: uid
vals: 1 item
alswiffin
Item givenname
type: givenname
vals: 1 item
Andy
Item telephonenumber
type: telephonenumber
vals: 1 item
12345
Item sn
type: sn
vals: 1 item
swiffin
[Response To: 38]



…(A number of other users are omitted, and here is the last one)



Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(2) "cn=YBear,ou=users,o=dundee" [6 results]
searchResEntry
objectName: cn=YBear,ou=users,o=dundee
attributes: 6 items
Item departmentnumber
type: departmentnumber
vals: 1 item
Ursine studies
Item mail
type: mail
vals: 1 item
y.bear@dundee.ac.uk
Item uid
type: uid
vals: 1 item
YBear
Item givenname
type: givenname
vals: 1 item
Yogi
Item telephonenumber
type: telephonenumber
vals: 1 item
88776655
Item sn
type: sn
vals: 1 item
Bear
[Response To: 38]
[Time: 0.011143000 seconds]
Lightweight-Directory-Access-Protocol
LDAPMessage searchResDone(2) [6 results]
messageID: 2
protocolOp: searchResDone (5)
searchResDone
resultCode: success (0)
matchedDN:
errorMessage:
[Response To: 38]
[Time: 0.011143000 seconds]



And that pretty much wraps things up, we have received the 6 users that were in the container and their relevant attributes. But what’s this? Another search request?




Frame 40 (254 bytes on wire, 254 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(3) "ou=users,o=dundee" wholeSubtree
searchRequest
baseObject: ou=users,o=dundee
scope: wholeSubtree (2)
derefAliases: derefAlways (3)
sizeLimit: 0
timeLimit: 0
typesOnly: False
Filter: (objectclass=inetOrgPerson)
filter: equalityMatch (3)
equalityMatch
attributeDesc: objectclass
assertionValue: inetOrgPerson
attributes: 12 items
Item: uid
Item: givenname
Item: initials
Item: sn
Item: manager
Item: departmentnumber
Item: telephonenumber
Item: mail
Item: title
Item: homephone
Item: mobile
Item: pager
[Response In: 41]



If you think it looks similar in text, comparing the binary shows in fact that we truly do have an identical request! And not surprisingly we get an identical set of results



Frame 41 (1275 bytes on wire, 1275 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(3) "cn=alswiffin,ou=users,o=dundee" [1 result]
messageID: 3
protocolOp: searchResEntry (4)
searchResEntry
objectName: cn=alswiffin,ou=users,o=dundee
attributes: 6 items
...I’m not showing you them all – they really are identical!
Lightweight-Directory-Access-Protocol
LDAPMessage searchResDone(3) [6 results]
messageID: 3
protocolOp: searchResDone (5)
searchResDone
resultCode: success (0)
matchedDN:
errorMessage:
[Response To: 40]
[Time: 0.002547000 seconds]



This is odd but not really a problem; Unified CM, for reasons best known to itself has asked for all of the information twice. Following this search Unified CM then performs a "mystery" single level search to return the attributes of the parent container, we are not sure why this is done. But following that, Unified CM then continues with a third subtly different search at our specified container:



Frame 46 (435 bytes on wire, 435 bytes captured)
Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(5) "ou=users,o=dundee" wholeSubtree
searchRequest
baseObject: ou=users,o=dundee
scope: wholeSubtree (2)
derefAliases: derefAlways (3)
sizeLimit: 0
timeLimit: 0
typesOnly: False
Filter: (objectclass=inetOrgPerson)
filter: equalityMatch (3)
equalityMatch
attributeDesc: objectclass
assertionValue: inetOrgPerson
attributes: 20 items
Item: uid
Item: givenname
Item: initials
Item: sn
Item: manager
Item: departmentnumber
Item: telephonenumber
Item: mail
Item: title
Item: homephone
Item: mobile
Item: pager
Item: objectClass
Item: javaSerializedData
Item: javaClassName
Item: javaFactory
Item: javaCodeBase
Item: javaReferenceAddress
Item: javaClassNames
Item: javaRemoteLocation

controls: 1 item
Item joint-iso-ccitt.16.840.1.113730.3.4.3
controlType: 2.16.840.1.113730.3.4.3 (joint-iso-ccitt.16.840.1.113730.3.4.3)
criticality: True
controlValue: 300902010F0101FF0101FF
[Response In: 47]



Items to note here are the list of extra attributes that are requested and most importantly the final section where control type 2.16.840.1.113730.3.4.3 is specified. This is a persistent search packet. In correct operation there will not be a normal search response packet. Instead any changes to an object within the searchbase will trigger a synchronization of that object. However, eDirectory returns:



Frame 47 (80 bytes on wire, 80 bytes captured)
Ethernet II, Src: Vmware_82:43:97 (00:50:56:82:43:97), Dst: Intel_71:d0:86 (00:0e:0c:71:d0:86)
Internet Protocol, Src: 134.36.1.101 (134.36.1.101), Dst: 134.36.40.227 (134.36.40.227)
Transmission Control Protocol, Src Port: ldap (389), Dst Port: 34195 (34195), Seq: 2648, Ack: 842, Len: 14
Lightweight-Directory-Access-Protocol
LDAPMessage searchResDone(5) other () [0 results]
messageID: 5
protocolOp: searchResDone (5)
searchResDone
resultCode: other (80)
matchedDN:
errorMessage:
[Response To: 46]



As we learned in the previous Appnote, Novell eDirectory does not support persistent search when dereference of aliases is requested [5]. The resultCode of 80 is an error code saying "I can’t do this". And the process now stops.



Let us review the process which has taken place:




  1. Unified CM bound to the eDirectory LDAP server twice.

  • With one of the connections it performed an empty base object search which elicited the information that persistent search is supported

  • One of the connections was then closed and with the other connection a search at the specified userbase was performed

  • eDirectory responded with all of the user information

  • Unified CM then asked for the whole search again

  • eDirectory duly returned an identical set of the information

  • Unified CM then queried the next level up from the user search base – I’m unsure why.

  • Unified CM then executed a search request at the search base but with persistent search specified

  • eDirectory baulked at this with an error code 80.



The point to note is that a successful search has taken place – reviewing the users tab on Unified CM shows our list of users there. But why did the second sync in 5 and 6 take place? I queried this with Cisco and the reply from the developers was that "The first sync obtains a count of entries. The second synch pulls all the data.". This may be what they had intended to do, but in fact as written it does the actual sync the first time as well. This is of no consequence to us, I would rather have two copies of the data than none! The important fact is that the data syncs down correctly and the users appear in the user list on Unified CM.



SunOne – how persistent search should work



I would like us to see how the search was supposed to work against a SunOne directory and so a copy of SunOne 5.2 was installed on a VM and populated with a few user objects.



The interaction between Unified CM and it follows pretty much the same path as with eDirectory (as one would expect)



Firstly we have the two bind requests and responses:



    LDAPMessage bindRequest(1) simple

LDAPMessage bindResponse(1)

LDAPMessage bindRequest(2) simple

LDAPMessage bindResponse(2)



Followed by the search request to review the supported extensions and controls:



Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(2) "" baseObject
searchRequest
baseObject:
scope: baseObject (0)
derefAliases: derefAlways (3)
Filter: (objectClass=*)
filter: present (7)
present: objectClass
attributes: 0 items
[Response In: 30]

Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(2) ""
searchResEntry
objectName:
attributes: 0 items
Item objectClass
type: objectClass
vals: 1 item
top
Item namingContexts
type: namingContexts
vals: 1 item
dc=dundee,dc=ac,dc=uk
Item supportedExtension
type: supportedExtension
vals: 27 items
2.16.840.1.113730.3.5.7
. …
1.3.6.1.4.1.4203.1.11.3
Item supportedControl
type: supportedControl
vals: 18 items
OID: 2.16.840.1.113730.3.4.3 (joint-iso-ccitt.16.840.1.113730.3.4.3)




And there we can see the persistent search control. After unbinding the redundant connection the normal search takes place



Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(2) "ou=users,dc=dundee,dc=ac,dc=uk" wholeSubtree
messageID: 2
protocolOp: searchRequest (3)
searchRequest
baseObject: ou=users,dc=dundee,dc=ac,dc=uk
scope: wholeSubtree (2)
derefAliases: derefAlways (3)
sizeLimit: 0
timeLimit: 0
typesOnly: False
Filter: (objectclass=inetOrgPerson)
filter: equalityMatch (3)
equalityMatch
attributes: 12 items
Item: uid
Item: givenname
Item: initials
Item: sn
Item: manager
Item: departmentnumber
Item: telephonenumber
Item: mail
Item: title
Item: homephone
Item: mobile
Item: pager
[Response In: 36]



SunOne sends each entry in a separate packet



Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(2) "uid=hFinn,ou=users,dc=dundee,dc=ac,dc=uk" [5 results]
searchResEntry
objectName: uid=hFinn,ou=users,dc=dundee,dc=ac,dc=uk
attributes: 5 items
Item uid
type: uid
vals: 1 item
hFinn
Item givenname
type: givenname
vals: 1 item
huckleberry
Item sn
type: sn
vals: 1 item
Finn
Item telephonenumber
type: telephonenumber
vals: 1 item
98765
Item mail
type: mail
vals: 1 item
h.finn@dundee.ac.uk


Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(2) "uid=aswiffin,ou=users,dc=dundee,dc=ac,dc=uk" [6 results]
searchResEntry
objectName: uid=aswiffin,ou=users,dc=dundee,dc=ac,dc=uk
attributes: 5 items
Item uid
type: uid
vals: 1 item
aswiffin
Item givenname
type: givenname
vals: 1 item
andy
Item sn
type: sn
vals: 1 item
swiffin
Item telephonenumber
type: telephonenumber
vals: 1 item
12345
Item mail
type: mail
vals: 1 item
a.l.swiffin@dundee.ac.uk



Following this, the whole search is repeated as before and then the mystery upper level search takes place. Following that Unified CM then asks for the persistent search:



No.     Time        
51 224.901865
Lightweight-Directory-Access-Protocol
LDAPMessage searchRequest(5) "ou=users,dc=dundee,dc=ac,dc=uk" wholeSubtree
messageID: 5
protocolOp: searchRequest (3)
searchRequest
baseObject: ou=users,dc=dundee,dc=ac,dc=uk
scope: wholeSubtree (2)
derefAliases: derefAlways (3)
sizeLimit: 0
timeLimit: 0
typesOnly: False
Filter: (objectclass=inetOrgPerson)
filter: equalityMatch (3)
equalityMatch
attributes: 20 items
Item: uid
Item: givenname
Item: initials
Item: sn
Item: manager
Item: departmentnumber
Item: telephonenumber
Item: mail
Item: title
Item: homephone
Item: mobile
Item: pager
Item: objectClass
Item: javaSerializedData
Item: javaClassName
Item: javaFactory
Item: javaCodeBase
Item: javaReferenceAddress
Item: javaClassNames
Item: javaRemoteLocation
[Response In: 53]
controls: 1 item
Item joint-iso-ccitt.16.840.1.113730.3.4.3
controlType: 2.16.840.1.113730.3.4.3 (joint-iso-ccitt.16.840.1.113730.3.4.3)
criticality: True
controlValue: 300902010F0101FF0101FF



NB, the timestamp above was 224.9. Nothing then happens, until a little later when I modify an object, by adding a departmentnumber attribute. The whole object resyncs including the new attribute:



No.     Time        
53 661.513422
Lightweight-Directory-Access-Protocol
LDAPMessage searchResEntry(5) "uid=aswiffin,ou=users,dc=dundee,dc=ac,dc=uk" [1 result]
searchResEntry
objectName: uid=aswiffin,ou=users,dc=dundee,dc=ac,dc=uk
attributes: 7 items
Item uid
type: uid
vals: 1 item
aswiffin
Item givenname
type: givenname
vals: 1 item
andy
Item sn
type: sn
vals: 1 item
swiffin
Item departmentnumber
type: departmentnumber
vals: 1 item
ICS
Item telephonenumber
type: telephonenumber
vals: 1 item
12345
Item mail
type: mail
vals: 1 item
a.l.swiffin@dundee.ac.uk
Item objectClass
type: objectClass
vals: 4 items
top
person
organizationalPerson
inetorgperson
[Response To: 51]
[Time: 436.611557000 seconds]
controls: 1 item
Item joint-iso-ccitt.16.840.1.113730.3.4.7
controlType: 2.16.840.1.113730.3.4.7 (joint-iso-ccitt.16.840.1.113730.3.4.7)
controlValue: 30030A0104



Thereafter any modification of an object in the userbase or the addition of a new object will cause the whole user object to sync down.





Here we see a new user "Adam Smith" has been added to the existing pair of Andy Swiffin and Huckleberry Finn. You will also notice that the 3 active users have replaced the 5 that are marked as inactive. These inactive users are the ones that were previously synchronized from eDirectory earlier in the day. The change of directory source has caused all of the users that were sync’d from that source to be now flagged inactive and they will be purged overnight.



This is how persistent search is supposed to work and it does seem very effective. Caution would need to be exercised however as the trigger of a resynchronization is not limited to those attributes that we are gathering. If, for instance, any other irrelevant attribute is modified, this too will trigger a resynchronization despite the fact that there has been no change as far as Unified CM is concerned. If a future version of eDirectory did support persistent search with alias dereference one would want to be very careful about pointing this at a production tree where, for instance, timestamp attributes are changing each time a user logs in and these would trigger a synchronization.



Readers of previous Appnotes in the series will already have an inkling as to the answer to the problem of the persistent search error (not that Unified CM 7 seems to be bothered by it).



As we saw then, eDirectory allows us to turn off this feature:





If this is done, the response from eDirectory to the search with a null baseobject does not include persistent search in the list of supported controls. As a result Unified CM is very well behaved, it asks for the search twice as before and then simply unbinds from eDirectory until the next timed search – perfect.



Once the users have synchronized onto Unified CM it is possible to enable LDAP authentication for users to access their telephone management web page as described in [1] for Unified CM V6. The LDAP server which is used for authentication can be the same one that was used for the synchronization or a different server provided that it also contains the same user set. LDAP authentication was found to work, just as it did with the two previous versions.



Conclusion



There is little difference in the response from eDirectory to that achieved when a true SunOne directory is used. Initially it looked as though persistent search might be a slight problem but turning it off in eDirectory caused a correct synchronization to occur, even leaving it on does not seem to be a problem as Unified CM copes with the error message that eDirectory reports.



From what I have seen I cannot see a reason why Novell eDirectory could not be added to the list of supported directories for Unified CM and hope that it soon will be.



I understand that Unity Connection 7.x also supports LDAP synchronization [7] and that this operates in a very similar way to the Communications Manager. Unity Connection also has a filter for filtering users which will be very useful as not all telephone users have voice mail and an LDAP attribute could be used to restrict this. By using LDAP authentication with Unity connection it should be possible to provide users with IMAP access to their voicemail using their standard credentials. I haven’t been able to test this yet but hope to in the not too distant future.



Once we have eDirectory as an official supported directory, a further gilding of the lily would be for Cisco to add in functionality so that a telephone number which is downloaded from the directory would be automatically applied to a device which is associated with the user. We would then achieve single point management of identity and user telephone number from within the directory - the holy grail!



References












Comment List
Anonymous
Related Discussions
Recommended