100% found this document useful (4 votes)
112 views

Download Complete Practical Spring LDAP: Using Enterprise Java-Based LDAP in Spring Data and Spring Framework 6 2nd Edition Varanasi Balaji PDF for All Chapters

LDAP

Uploaded by

gyselgabi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (4 votes)
112 views

Download Complete Practical Spring LDAP: Using Enterprise Java-Based LDAP in Spring Data and Spring Framework 6 2nd Edition Varanasi Balaji PDF for All Chapters

LDAP

Uploaded by

gyselgabi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Download Full Version ebookmass - Visit ebookmass.

com

Practical Spring LDAP: Using Enterprise Java-Based


LDAP in Spring Data and Spring Framework 6 2nd
Edition Varanasi Balaji

https://ebookmass.com/product/practical-spring-ldap-using-
enterprise-java-based-ldap-in-spring-data-and-spring-
framework-6-2nd-edition-varanasi-balaji/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmass.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Practical Spring LDAP: Using Enterprise Java-Based LDAP in


Spring Data and Spring Framework 6 2nd Edition Varanasi
Balaji
https://ebookmass.com/product/practical-spring-ldap-using-enterprise-
java-based-ldap-in-spring-data-and-spring-framework-6-2nd-edition-
varanasi-balaji/
ebookmass.com

Pro Spring Security: Securing Spring Framework 6 and Boot


3–based Java Applications, Third Edition Massimo Nardone

https://ebookmass.com/product/pro-spring-security-securing-spring-
framework-6-and-boot-3-based-java-applications-third-edition-massimo-
nardone/
ebookmass.com

Beginning Spring Data: Data Access and Persistence for


Spring Framework 6 and Boot 3 Andres Sacco

https://ebookmass.com/product/beginning-spring-data-data-access-and-
persistence-for-spring-framework-6-and-boot-3-andres-sacco/

ebookmass.com

Corn Book for Young Folk Charles Burgess Williams

https://ebookmass.com/product/corn-book-for-young-folk-charles-
burgess-williams/

ebookmass.com
The Arctic: What Everyone Needs to Know Klaus Dodds

https://ebookmass.com/product/the-arctic-what-everyone-needs-to-know-
klaus-dodds/

ebookmass.com

Video Production: Disciplines and Techniques 12th Edition,


(Ebook PDF)

https://ebookmass.com/product/video-production-disciplines-and-
techniques-12th-edition-ebook-pdf/

ebookmass.com

iOS Architecture Patterns: MVC, MVP, MVVM, VIPER, and VIP


in Swift 1st Edition Raúl Ferrer García

https://ebookmass.com/product/ios-architecture-patterns-mvc-mvp-mvvm-
viper-and-vip-in-swift-1st-edition-raul-ferrer-garcia/

ebookmass.com

Oracles Always Win (Willow Lake Supernaturals Book 3) Lori


Ames

https://ebookmass.com/product/oracles-always-win-willow-lake-
supernaturals-book-3-lori-ames/

ebookmass.com

New Technologies for Emission Control in Marine Diesel


Engines Kuwahara

https://ebookmass.com/product/new-technologies-for-emission-control-
in-marine-diesel-engines-kuwahara/

ebookmass.com
Solferino 21: Warfare, Civilians and Humanitarians in the
Twenty-First Century Hugo Slim

https://ebookmass.com/product/solferino-21-warfare-civilians-and-
humanitarians-in-the-twenty-first-century-hugo-slim/

ebookmass.com
Practical Spring
LDAP
Using Enterprise Java-Based LDAP in
Spring Data and Spring Framework 6

Second Edition

Balaji Varanasi
Andres Sacco
Practical Spring LDAP
Using Enterprise Java-Based
LDAP in Spring Data and Spring
Framework 6
Second Edition

Balaji Varanasi
Andres Sacco
Practical Spring LDAP: Using Enterprise Java-Based LDAP in Spring Data and
Spring Framework 6, Second Edition
Balaji Varanasi Andres Sacco
Salt Lake City, UT, USA Buenos Aires, Buenos Aires, Argentina

ISBN-13 (pbk): 979-8-8688-0001-6 ISBN-13 (electronic): 979-8-8688-0002-3


https://doi.org/10.1007/979-8-8688-0002-3

Copyright © 2023 by Balaji Varanasi and Andres Sacco


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Melissa Duffy
Development Editor: James Markham
Coordinating Editor: Gryffin Winkler
Cover designed by eStudioCalamar
Cover image by iulia_cristiana on unsplash (www.unsplash.com/)
Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004,
U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-sbm.com, or visit
www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer
Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail booktranslations@springernature.com; for reprint,
paperback, or audio rights, please e-mail bookpermissions@springernature.com.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub (https://github.com/Apress). For more detailed information, please visit https://www.
apress.com/gp/services/source-code.
Paper in this product is recyclable
To my grandparents who taught me the importance of
learning new things all the time.
To my wife and children for supporting me while
writing this book.
Table of Contents
About the Authors���������������������������������������������������������������������������������������������������� xi

About the Technical Reviewer������������������������������������������������������������������������������� xiii

Acknowledgments���������������������������������������������������������������������������������������������������xv
Introduction�����������������������������������������������������������������������������������������������������������xvii

Chapter 1: Introduction to LDAP������������������������������������������������������������������������������� 1


LDAP Overview������������������������������������������������������������������������������������������������������������������������������ 2
Directory vs. Database������������������������������������������������������������������������������������������������������������ 2
Information Model������������������������������������������������������������������������������������������������������������������������� 3
Object Classes������������������������������������������������������������������������������������������������������������������������������ 6
Directory Schema������������������������������������������������������������������������������������������������������������������������� 8
Naming Model������������������������������������������������������������������������������������������������������������������������������� 9
Functional Model������������������������������������������������������������������������������������������������������������������������ 11
Security Model���������������������������������������������������������������������������������������������������������������������������� 12
LDIF Format�������������������������������������������������������������������������������������������������������������������������������� 13
LDAP History������������������������������������������������������������������������������������������������������������������������������� 14
LDAP Vendors������������������������������������������������������������������������������������������������������������������������������ 15
Sample Application��������������������������������������������������������������������������������������������������������������������� 17
Summary������������������������������������������������������������������������������������������������������������������������������������ 18

Chapter 2: Java Support for LDAP�������������������������������������������������������������������������� 19


LDAP Using JNDI������������������������������������������������������������������������������������������������������������������������� 21
Connect to LDAP������������������������������������������������������������������������������������������������������������������������� 21
LDAP Operations������������������������������������������������������������������������������������������������������������������������� 25
Closing Resources���������������������������������������������������������������������������������������������������������������������� 25
Creating a New Entry������������������������������������������������������������������������������������������������������������������ 25
v
Table of Contents

Updating an Entry����������������������������������������������������������������������������������������������������������������������� 28
Removing an Entry���������������������������������������������������������������������������������������������������������������������� 30
Searching Entries������������������������������������������������������������������������������������������������������������������������ 31
Check How the Operations Work������������������������������������������������������������������������������������������������� 33
JNDI Drawbacks�������������������������������������������������������������������������������������������������������������������������� 38
Summary������������������������������������������������������������������������������������������������������������������������������������ 38

Chapter 3: Introducing Spring LDAP����������������������������������������������������������������������� 39


Motivation����������������������������������������������������������������������������������������������������������������������������������� 40
Documentation and Source Code Spring LDAP��������������������������������������������������������������������������� 40
Spring LDAP Packaging�������������������������������������������������������������������������������������������������������������� 41
Installing Spring LDAP Using Maven������������������������������������������������������������������������������������������� 42
Spring LDAP Archetypes������������������������������������������������������������������������������������������������������������� 43
Creating Projects Using IntelliJ��������������������������������������������������������������������������������������������������� 58
Spring LDAP Hello World������������������������������������������������������������������������������������������������������������� 61
Spring ApplicationContext����������������������������������������������������������������������������������������������������������� 65
Spring-Powered Search Client���������������������������������������������������������������������������������������������������� 65
Spring LdapTemplate Operations������������������������������������������������������������������������������������������������ 70
Add Operation����������������������������������������������������������������������������������������������������������������������������� 70
Modify Operation������������������������������������������������������������������������������������������������������������������������� 71
Deleting Operation���������������������������������������������������������������������������������������������������������������������� 72
Summary������������������������������������������������������������������������������������������������������������������������������������ 75

Chapter 4: Testing LDAP Code��������������������������������������������������������������������������������� 77


Concepts About Testing��������������������������������������������������������������������������������������������������������������� 77
Unit Testing���������������������������������������������������������������������������������������������������������������������������� 78
Mock Testing������������������������������������������������������������������������������������������������������������������������� 80
Integration Testing����������������������������������������������������������������������������������������������������������������� 81
Libraries to Do Tests�������������������������������������������������������������������������������������������������������������������� 82
JUnit�������������������������������������������������������������������������������������������������������������������������������������� 82
Mockito���������������������������������������������������������������������������������������������������������������������������������� 88
Testcontainers����������������������������������������������������������������������������������������������������������������������� 91

vi
Table of Contents

Creating the Tests����������������������������������������������������������������������������������������������������������������������� 94


Mocking the Templates��������������������������������������������������������������������������������������������������������� 97
Testing Using Embedded Server�������������������������������������������������������������������������������������������� 99
Moving to Tests with Testcontainers������������������������������������������������������������������������������������ 103
Summary���������������������������������������������������������������������������������������������������������������������������������� 105

Chapter 5: Advanced Spring LDAP������������������������������������������������������������������������ 107


JNDI Object Factories��������������������������������������������������������������������������������������������������������������� 107
Spring and Object Factories������������������������������������������������������������������������������������������������������ 111
DAO Implementation Using Object Factory������������������������������������������������������������������������������� 112
Implementing Finder Methods�������������������������������������������������������������������������������������������������� 115
Create Method�������������������������������������������������������������������������������������������������������������������������� 120
Update Method�������������������������������������������������������������������������������������������������������������������������� 122
Delete Method��������������������������������������������������������������������������������������������������������������������������� 124
Summary���������������������������������������������������������������������������������������������������������������������������������� 125

Chapter 6: Searching LDAP����������������������������������������������������������������������������������� 127


LDAP Search Criteria����������������������������������������������������������������������������������������������������������������� 127
Base Parameter������������������������������������������������������������������������������������������������������������������� 127
Scope Parameter����������������������������������������������������������������������������������������������������������������� 128
Filter Parameter������������������������������������������������������������������������������������������������������������������� 129
Optional Parameters������������������������������������������������������������������������������������������������������������ 130
LDAP Injection��������������������������������������������������������������������������������������������������������������������� 131
Spring LDAP Filters������������������������������������������������������������������������������������������������������������������� 132
EqualsFilter�������������������������������������������������������������������������������������������������������������������������� 136
LikeFilter������������������������������������������������������������������������������������������������������������������������������ 137
PresentFilter������������������������������������������������������������������������������������������������������������������������ 139
NotPresentFilter������������������������������������������������������������������������������������������������������������������� 140
Not Filter������������������������������������������������������������������������������������������������������������������������������ 141
GreaterThanOrEqualsFilter�������������������������������������������������������������������������������������������������� 142
LessThanOrEqualsFilter������������������������������������������������������������������������������������������������������� 143
AndFilter������������������������������������������������������������������������������������������������������������������������������ 144

vii
Table of Contents

OrFilter��������������������������������������������������������������������������������������������������������������������������������� 145
HardcodedFilter������������������������������������������������������������������������������������������������������������������� 146
WhitespaceWildcardsFilter�������������������������������������������������������������������������������������������������� 147
Handling Special Characters����������������������������������������������������������������������������������������������� 148
LDAP Query Builder Parameters����������������������������������������������������������������������������������������������� 148
Summary���������������������������������������������������������������������������������������������������������������������������������� 152

Chapter 7: Sorting and Paging Results����������������������������������������������������������������� 153


LDAP Controls��������������������������������������������������������������������������������������������������������������������������� 153
Identifying Supported Controls������������������������������������������������������������������������������������������������� 156
JNDI and Controls��������������������������������������������������������������������������������������������������������������������� 160
Spring LDAP and Controls��������������������������������������������������������������������������������������������������������� 162
Sort Control������������������������������������������������������������������������������������������������������������������������������� 163
Implementing Custom DirContextProcessor����������������������������������������������������������������������������� 171
Paged Search Controls�������������������������������������������������������������������������������������������������������������� 177
Summary���������������������������������������������������������������������������������������������������������������������������������� 186

Chapter 8: Object-Directory Mapping������������������������������������������������������������������� 187


Spring ODM Basics������������������������������������������������������������������������������������������������������������������� 188
ODM Metadata�������������������������������������������������������������������������������������������������������������������������� 191
ODM Service Class�������������������������������������������������������������������������������������������������������������������� 195
Creating Custom Converter������������������������������������������������������������������������������������������������������� 201
Summary���������������������������������������������������������������������������������������������������������������������������������� 211

Chapter 9: LDAP Transactions������������������������������������������������������������������������������ 213


Transaction Basics�������������������������������������������������������������������������������������������������������������������� 213
Local vs. Global Transactions���������������������������������������������������������������������������������������������������� 215
Programmatic vs. Declarative Transactions������������������������������������������������������������������������������ 217
Programmatically���������������������������������������������������������������������������������������������������������������������� 217
Declaratively����������������������������������������������������������������������������������������������������������������������������� 218
Spring Transaction Abstraction������������������������������������������������������������������������������������������������� 218
Declarative Transactions Using Spring�������������������������������������������������������������������������������������� 220

viii
Table of Contents

LDAP Transaction Support��������������������������������������������������������������������������������������������������������� 224


Spring LDAP Transaction Support��������������������������������������������������������������������������������������������� 225
Compensating Transactions������������������������������������������������������������������������������������������������������ 226
Summary���������������������������������������������������������������������������������������������������������������������������������� 243

Chapter 10: Odds and Ends���������������������������������������������������������������������������������� 245


Authentication Using Spring LDAP�������������������������������������������������������������������������������������������� 245
Handling Authentication Exceptions����������������������������������������������������������������������������������������� 252
Parsing LDIF Data���������������������������������������������������������������������������������������������������������������������� 255
LDAP Connection Pooling���������������������������������������������������������������������������������������������������������� 261
Built-In Connection Pooling������������������������������������������������������������������������������������������������������� 261
Spring LDAP Connection Pooling���������������������������������������������������������������������������������������������� 262
Pool Validation��������������������������������������������������������������������������������������������������������������������������� 267
Summary���������������������������������������������������������������������������������������������������������������������������������� 269

Appendix A: Setting Up Environment Tools����������������������������������������������������������� 271

Appendix B: Recommended and Alternative Tools����������������������������������������������� 281

Appendix C: Set Up LDAP Server��������������������������������������������������������������������������� 287

Appendix D: Opening a Project����������������������������������������������������������������������������� 307

Appendix E: Further Reading�������������������������������������������������������������������������������� 311

Index��������������������������������������������������������������������������������������������������������������������� 313

ix
About the Authors
Balaji Varanasi is a software development manager and technology entrepreneur. He
has over 13 years of experience architecting and developing Java/.NET applications and,
more recently, iPhone apps. During this period, he has worked in the areas of security,
web accessibility, search, and enterprise portals. He has a master’s degree in computer
science and serves as adjunct faculty, teaching programming and information system
courses. When not programming, he enjoys spending time with his lovely wife in Salt
Lake City, Utah.

Andres Sacco has been working as a developer since


2007 in different languages, including Java, PHP, Node.js,
Scala, and Kotlin. His background is mostly in Java and the
libraries or frameworks associated with this language. At
most of the companies he worked for, he researched new
technologies to improve the performance, stability, and
quality of the applications of each company. In 2017, he
started to find new ways to optimize the transference of data
between applications to reduce the cost of infrastructure. He
suggested some actions, some applicable in all of the manual microservices and others
in just a few. All of this work includes creating a series of theoretic-practical projects
(available on Manning.com). Recently, he coauthored an Apress book titled Beginning
Scala 3. He also published a set of theoretic-practical projects about uncommon ways of
testing, such as architecture tests and chaos engineering.

xi
About the Technical Reviewer
Manuel Jordan is an autodidactic developer and researcher who enjoys learning new
technologies for his own experiments about creating new integrations among them.
Manuel won the 2010 Springy Award – Community Champion and Spring Champion
2013. In his little free time, he reads the Bible and composes music on his bass
and guitar.
You can reach him through his Twitter account, @dr_pompeii.

xiii
Acknowledgments
I would like to thank my family members and friends for their encouragement and
support during the writing of this book:
• My wife, Gisela, who was always patient when I spent long hours at
my computer desk working on this book

• My little daughter, Francesca, who helped me relax while writing


each chapter

• My baby, Allegra, who is the new family member and my inspiration


to write this book

• My friends, German Canale and Julian Delley, who always trusted me


to write a book and supported me during tough times

Specially mentioning Manuel Jordan for guiding me in improving the quality of


the book.
My sincere thanks to the beautiful team at Apress for their support during the
publication of this book. Thanks to Shonmirin P.A. for providing excellent support.
Finally, thanks to Mark Powers and Melissa Duffy for suggesting and allowing me to
write a book. Also, I want to mention the great job that Balaji Varanasi did with the first
edition of this book which gave the base to write the second edition.

xv
Introduction
Practical Spring LDAP provides complete coverage of Spring LDAP, a framework
designed to take the pain out of LDAP programming. This book starts by explaining the
fundamental concepts of LDAP and showing the reader how to set up the development
environment. It then dives into Spring LDAP, analyzing the problems it is designed to
solve. After that, the book focuses on the practical aspects of unit testing and integration
testing with LDAP. An in-depth treatment of LDAP controls and Spring LDAP features,
such as Object-Directory Mapping and LDIF (LDAP Data Interchange Format) parsing,
follows this. Finally, it concludes with discussions on LDAP authentication and
connection pooling.

What the Book Covers


Chapter 1 starts with an overview of directory servers. It then discusses the basics of
LDAP and introduces the four LDAP information models. It finishes with an introduction
to the LDIF format used for representing LDAP data.
Chapter 2 focuses on the Java Naming and Directory Interface (JNDI). In this chapter,
you look at creating applications that interact with LDAP using plain JNDI.
Chapter 3 explains Spring LDAP and why it is an important option in an enterprise
developer’s repertoire. In this chapter, you set up the development environment to
create Spring LDAP applications and other important tools, such as Maven and a test
LDAP server. Finally, you implement a basic but complete Spring LDAP application
using annotations.
Chapter 4 covers the fundamentals of unit and integration testing. You then
look at setting up an embedded LDAP server for unit testing your application code;
alternatively, you will see how to use Testcontainers to run LDAP using a docker image.
You also review available tools for generating test data. Finally, you use the Mockito
library to mock test LDAP code.

xvii
Introduction

Chapter 5 introduces the basics of JNDI object factories and uses these factories
for creating objects that are more meaningful to the application. You then examine
a complete Data Access Object (DAO) layer implementation using Spring LDAP and
object factories.
Chapter 6 covers LDAP search. This chapter begins with the underlying ideas of
LDAP search. I then introduce various Spring LDAP filters that make LDAP searching
easier. Finally, you look at creating a custom search filter to address situations where the
current set is insufficient.
Chapter 7 provides an in-depth overview of LDAP controls that can be used for
extending LDAP server functionality. Then it moves on to sorting and paging LDAP
results using sort and page controls.
Chapter 8 deals with Object-Directory Mapping (ODM), a feature in Spring LDAP. In
this chapter, you look at bridging the gap between the domain model and the directory
server. You then re-implement the DAO using ODM concepts.
Chapter 9 introduces the important ideas of transactions and transactional integrity
before analyzing the transaction abstractions provided by Spring Framework. Finally, it
takes a look at Spring LDAP’s compensating transaction support.
Chapter 10 starts with implementing authentication, the most common operation
against LDAP. It then deals with parsing LDIF files using another feature introduced
in Spring. I end the chapter by looking at the connection pooling support provided by
Spring LDAP.

Target Audience
Practical Spring LDAP is intended for developers interested in building Java/JEE
applications using LDAP. It also teaches techniques for creating unit/integration tests for
LDAP applications. The book assumes basic familiarity with Spring Framework; prior
exposure to LDAP is helpful but optional. Developers already familiar with Spring LDAP
will find best practices and examples to help them get the most out of the framework.

xviii
Introduction

P
 rerequisites
You should install Java JDK1 21 or higher on your machine, Maven2 3.8.0 or higher, and
some IDE. Some options for the IDE could be Eclipse,3 IntelliJ IDEA,4 Visual Studio
Code,5 and others, but you can choose which is the best for you.
To reduce the complexity of installing all LDAP vendors on your machine, I
recommend you install Docker6 and use it to run each LDAP. The use and installation of
Docker are outside the scope of this book, but there are some tutorials7 or cheatsheet8
with the most common commands.

Note If you don’t have it installed on your machine, you can check Appendixes A,
B, and C, which have information about installing the different tools and loading the
information on LDAP.

After installing all the tools, you must check if they are correctly installed before
reading the different chapters.
In the case of Java, you need to run the following command:
% java -version
openjdk 21 2023-09-19
OpenJDK Runtime Environment (build 21+35-2513)
OpenJDK 64-Bit Server VM (build 21+35-2513, mixed mode, sharing)

After that, you need to check if the version of Maven is correct using this command:
% mvn --version
Apache Maven 3.9.1
Maven home: /usr/share/maven

1
https://jdk.java.net/
2
https://maven.apache.org/
3
https://www.eclipse.org/downloads
4
https://www.jetbrains.com/es-es/idea/
5
https://code.visualstudio.com/
6
https://www.docker.com/
7
https://docker-curriculum.com/
8
https://michaelhaar.dev/my-docker-compose-cheatsheet

xix
Introduction

Last, if you want to check whether Docker runs correctly on your machine, you can
do that using the following command:
% docker --version
Docker version 24.0.2, build cb74dfc

Remember that I mentioned that Docker is optional. It’s only recommended for
reducing the complexity of installing LDAP vendors on your machine.

Downloading Source Code


The source code for the examples in this book can be downloaded from www.apress.com.
For detailed information about locating this book’s source code, visit www.apress.com/gp/
services/source-code. The code is organized by chapter and can be built using Maven.

Questions?
If you have any questions or suggestions, contact the author at sacco.andres@gmail.com.

xx
CHAPTER 1

Introduction to LDAP
We all deal with directories daily. We use a telephone directory to look up phone
numbers. When visiting a library, we use the library catalog to look up the books we
want to read. We use the file system directory with computers to store our files and
documents. Simply put, a directory is a repository of information. The information is
usually organized so that it can be retrieved easily.
Directories on a network are typically accessed using the client/server
communication model. Applications wanting to read or write data to a directory
communicate with specialized servers. The directory server performs a read or write
operation on the actual directory. Figure 1-1 shows this client/server interaction.

Figure 1-1. Directory server and client interaction

The communication between the directory server and client applications is usually
accomplished using standardized protocols. The Lightweight Directory Access Protocol
(LDAP) provides a standard protocol for communicating with a directory. The directory
servers that implement the LDAP protocol are usually called LDAP servers. The LDAP

1
© Balaji Varanasi and Andres Sacco 2023
B. Varanasi and A. Sacco, Practical Spring LDAP, https://doi.org/10.1007/979-8-8688-0002-3_1
Chapter 1 Introduction to LDAP

protocol is based on an earlier X.5001 standard but is significantly simpler (lightweight)


and easily extensible. Over the years, the LDAP protocol went through iterations and is
currently at version 3.0.

LDAP Overview
LDAP defines a message protocol used by directory clients and directory servers. LDAP
can be better understood by considering the following four models it is based on:

• The Information model determines the structure of information


stored in the directory.

• The Naming model defines how information is organized and


identified in the directory.

• The Functional model defines the operations performed on the


directory.

• The Security model defines how to protect information from


unauthorized access.

We will look at each of these models in the following sections.

Directory vs. Database


Beginners often need clarification and picture an LDAP directory as a relational
database. Like a database, an LDAP directory stores information. However, several key
characteristics set a directory apart from relational databases.
LDAP directories typically store data that is relatively static. For example, employee
information stored in LDAP, such as their phone number or name, does not change
daily. However, users and applications look up this information very frequently. Since
the data in a directory is accessed more often than updated, LDAP directories follow the
WORM principle2, 3 and are heavily optimized for read performance. Placing data that
change quite often in LDAP does not make sense.

1
https://docs.oracle.com/javase/jndi/tutorial/ldap/models/x500.html
2
https://en.wikipedia.org/wiki/Write_Once_Read_Many
3
https://www.techtarget.com/searchstorage/definition/WORM-write-once-read-many

2
Chapter 1 Introduction to LDAP

Relational databases employ referential integrity and locking techniques to ensure


data consistency. The type of data stored in LDAP usually does not warrant such strict
consistency requirements. Hence, most of these features need to be present on LDAP
servers. Also, transactional semantics to roll back transactions are not defined under
LDAP specification.
Relational databases follow normalization principles to avoid data duplication
and redundancy. On the other hand, LDAP directories are organized in a hierarchical,
object-oriented way. This organization violates some of the normalization principles.
Also, there needs to be a concept of table joins in LDAP.
Even though directories lack several of the RDBMS4 features mentioned earlier, many
modern LDAP directories are built on top of relational databases such as DB2,5 MySQL,6
and PostgreSQL.7
At some point, LDAP has similar characteristics to nonrelational databases like
Cassandra,8 MongoDB,9 and many others where the performance of the write/read, high
availability, and scalability are more relevant than the consistency.

Information Model
The basic unit of information stored in LDAP is an entry. Entries hold information about
real-world objects such as employees, servers, printers, and organizations. Each entry in
an LDAP directory comprises zero or more attributes. Attributes are key-value pairs that
hold information about the object the entry represents. The key portion of an attribute
is also called the attribute type and describes the information that can be stored in the
attribute. The value portion of the attribute contains the actual information. Table 1-1
shows a portion of an entry representing an employee. The left column in the entry
contains the attribute types, and the right column holds the attribute values.

4
https://www.oracle.com/in/database/what-is-a-relational-database/
5
https://www.ibm.com/products/db2
6
https://www.mysql.com/
7
https://www.postgresql.org/
8
https://cassandra.apache.org/_/index.html
9
https://www.mongodb.com/

3
Chapter 1 Introduction to LDAP

Table 1-1. Employee LDAP Entry


Employee Entry

objectClass inetOrgPerson
givenName John
surname Smith
mail john@inflix.com
jsmith@inflix.com
mobile +1 801 100 1000

Note Attribute names, by default, are case-insensitive. However, it is


recommended to use camel case format in LDAP operations.

You will notice that the mail attribute has two values. Attributes that are allowed to
hold multiple values are called multivalued attributes. Single-valued attributes, on the
other hand, can only hold a single value. The LDAP specification does not guarantee the
order of the values in a multivalued attribute.
Each attribute type is associated with a syntax that dictates the format of the
data stored as an attribute value. For example, the mobile attribute type has a
telephoneNumber syntax. This forces the attribute to hold a string value with a length
between 1 and 32.
Additionally, the syntax also defines the attribute value behavior during search
operations. For example, the givenName attribute has the syntax DirectoryString. This
syntax enforces that only alphanumeric characters are allowed as values. Table 1-2 lists
some common attributes and their associated syntax description.

4
Chapter 1 Introduction to LDAP

Table 1-2. Common Entry Attributes


Attribute Type Syntax Description

commonName DirectoryString Stores the common name of a person.


company DirectoryString Stores the company’s name.
employeeNumber DirectoryString Stores the employee’s identification number in the
organization.
givenName DirectoryString Stores the user’s first name.
jpegPhoto Binary Stores one or more images of the person.
mail IA5 String Stores a person’s SMTP mail address.
mobile TelephoneNumber Stores a person’s mobile number.
postalAddress Postal Address Stores the user’s ZIP or postal code.
postalCode DirectoryString Stores the user’s ZIP or postal code.
st DirectoryString Stores the state or province name.
street DirectoryString Stores the street address.
surname DirectoryString Stores the last name of the person.
telephoneNumber TelephoneNumber Stores the person’s primary telephone number.
uid DirectoryString Stores the user id.
title DirectoryString Stores the name of the position or the company’s function.
wwwhomepage DirectoryString Stores the official web page of the company.

The attributes in Table 1-2 are the most used for the developers and tools. Still, there
is a big list of other attributes depending on whether your vendor or the tool supports
it or not; for example, on the official web page10 of Microsoft, all the attributes are
supported for the Active Directory.

10
https://learn.microsoft.com/en-us/windows/win32/adschema/attributes-all

5
Chapter 1 Introduction to LDAP

Object Classes
In object-oriented languages, such as Java, we create a class and use it as a blueprint for
creating objects. The class defines the attributes/data (and behavior/methods) that these
instances can have. Similarly, object classes in LDAP determine the attributes an LDAP
entry can have. These object classes also define which attributes are mandatory and
which are optional. Every LDAP entry has a special attribute aptly named objectClass
that holds the object class it belongs to. Looking at the objectClass value in the employee
entry in Table 1-1, we can conclude that the entry belongs to the inetOrgPerson class.
Table 1-3 shows the required and optional attributes in a standard LDAP person object
class. The cn attribute holds the person’s common name, whereas the sn attribute holds
the person’s family name or surname.

Table 1-3. Person Object Class


Required Attributes Optional Attributes

sn description
telephoneNumber
cn userPassword
objectClass seeAlso

As in Java, an object class can extend other object classes. This inheritance will
allow the child object class to inherit parent class attributes. For example, the person
object class defines attributes such as common name and surname. The object class
inetOrgPerson extends the person class and thus inherits all the person’s attributes.
Additionally, inetOrgPerson defines attributes required for a person working in an
organization, such as departmentNumber and employeeNumber. One special object class,
namely, top, does not have any parents. All other object classes are decedents of top
and inherit all the attributes declared in it. The top object class includes the mandatory
objectClass attribute. Figure 1-2 shows the object inheritance.

6
Chapter 1 Introduction to LDAP

Figure 1-2. LDAP object inheritance

Most LDAP implementations come with standard object classes that can be used out of
the box. Table 1-4 lists some of these LDAP object classes and their commonly used attributes.

Table 1-4. Common LDAP Object Classes


Object Class Attributes Description

top objectClass Defines the root object class. All other


object classes must extend this class.
organization o Represents a company or an organization.
The o attribute typically holds the name
of the organization.
organizationalUnit ou Represents a department or similar
entity inside an organization.
person sn Represents a person in the directory
cn and requires the sn (surname) and cn
telephoneNumber (common name) attributes.
userPassword
organizationalPerson registeredAddress Subclasses that represent a person in
postalAddress postalCode an organization.
inetOrgPerson uid departmentNumber It provides additional attributes and can
employeeNumber be used to represent a person working
givenName manager in today’s Internet- and intranet-based
organization. The uid attribute holds the
person’s username or user id.

7
Chapter 1 Introduction to LDAP

On Oracle’s official website,11 you can find the list of LDAP object classes with
information about the Request for Comments (RFC), which added each object class.

Note In this book, you will see many references to RFCs. Request for Comments
(RFC) is a series of technical documents produced by the Internet Engineering Task
Force (IETF)12 that specify certain standards.
Each RFC has a number as part of the name and a series of sections with the
specification. An RFC could become obsolete to many other RFCs because a new
specification about certain technology appears, for example, a new version of LDAP.
On the RFC Editor web page,13 you can find information about RFCs and the
publication process of the new one.

Directory Schema
The LDAP directory schema is a set of rules determining the type of information stored
in a directory. Schemas can be considered packaging units and contain attribute type
definitions and object class definitions. The schema rules are verified before an entry
can be stored in LDAP. This schema checking ensures that the entry has all the required
attributes and contains no attributes not part of the schema. Figure 1-3 represents a
generic LDAP schema.

Figure 1-3. LDAP generic schema

11
https://docs.oracle.com/cd/E24001_01/oid.1111/e10035/schema_objclass.htm
12
https://www.ietf.org/
13
https://www.rfc-editor.org/

8
Chapter 1 Introduction to LDAP

Like databases, directory schemas must be well designed to address issues like data
redundancy. Before implementing your schema, it is worth looking at publicly available
standard schemas. These standard schemas often contain all definitions to store the
required data and, more importantly, ensure interoperability across other directories.

Naming Model
The LDAP Naming model defines how entries are organized in a directory. It also
determines how a particular entry can be uniquely identified. The Naming model
recommends that entries be stored logically in a hierarchical fashion. This entry tree
is often called a directory information tree (DIT). Figure 1-4 provides an example of a
generic directory tree.

Figure 1-4. Generic DIT

The tree’s root is usually referred to as the base or suffix of the directory. This entry
represents the organization that owns the directory. The format of suffixes can vary
from implementation to implementation, but generally, there are three recommended
approaches, as listed in Figure 1-5.

Figure 1-5. Directory suffix naming conventions

9
Chapter 1 Introduction to LDAP

Note DC stands for domain component.

The first recommended technique is to use the organization’s domain name as the
suffix. For example, if the organization’s domain name is example.com, the directory
suffix will be o=example.com. The second technique also uses the domain name, but
each name component is prepended with “dc=” and joined by commas. So the domain
name example.com would result in a suffix dc=example, dc=com. This technique is
proposed in RFC 224714 and is popular with Microsoft Active Directory. The third
technique uses the X.500 model and creates a suffix in the format o=organization name,
c=country code. In the United States, the suffix for the organization example would be
o=example, c=us.
The naming model also defines naming and uniquely identifying entries in a
directory. Entries with a common immediate parent are uniquely identified via their
relative distinguished name (RDN), also called distinguished name (DN). The RDN is
computed using one or more attribute/value pairs of the entry. In its simplest case, RDN
is usually of the form attribute-name = attribute value. Figure 1-6 provides a simplified
representation of an organization directory. Each person entry under ou=employees has
a unique uid. So the RDN for the first person entry would be uid=emp1, where emp1 is
the employee’s user id.

Figure 1-6. Example of an organization directory

14
https://www.ietf.org/rfc/rfc2247.txt

10
Chapter 1 Introduction to LDAP

Note The distinguished name is not an actual attribute in the entry. It is a logical


name associated with the entry.

It is important to remember that RDN cannot be used to uniquely identify the entry
in the entire tree. However, this can be easily done by combining the RDNs of all the
entries in the path from the top of the tree to the entry. The result of this combination
is referred to as distinguished name (DN). In Figure 1-6, the DN for person 1 would be
uid=emp1, ou=employees, dc=example, dc=com. Since the DN is made by combining
RDNs, if an entry’s RDN changes, the DNs of that entry and all its child entries
also change.
There can be situations where a set of entries does not have a unique attribute. In
those scenarios, one option is to combine multiple attributes to create uniqueness. For
example, we can use the consumer’s common name and email address in the previous
directory as an RDN. Multivalued RDNs are represented by separating each attribute
pair with a +, like so:

cn =  Balaji  Varanasi +            mail=balaji@inflinx.com

Some special characters on the RDN must be escaped to prevent different


problems. The special characters are + (plus), = (equals), < (less than), > (greater than), ;
(semicolon), , (comma), \ (backslash), # (number sign), and ”.
There are different approaches to escape the characters, like adding the backslash
(“\” ASCII 92) before the special character; this approach is the most commonly used.
The other replaces the special characters with a backslash and hexadecimal digit, and
the last one surrounds the attribute’s value with quotation marks (“”).

Note Multivalued RDNs are usually discouraged. Creating a unique sequence


attribute is recommended in those scenarios to ensure uniqueness.

Functional Model
The LDAP Functional model describes the access and modification operations that can
be performed on the directory using the LDAP protocol. These operations fall into three
categories: query, update, and authentication.

11
Chapter 1 Introduction to LDAP

The query operations are used to search and retrieve information from a directory.
So whenever some information needs to be read, a search query must be constructed
and executed against LDAP. The search operation takes a starting point within DIT, the
search depth, and the attributes an entry must have for a match. In Chapter 6, you’ll
delve deep into searching and look at all the available options.
The update operations add, modify, delete, and rename directory entries. As the
name suggests, the add operation adds a new entry to the directory. This operation
requires the DN of the entry to be created and a set of attributes that constitute the
entry. The delete operation takes a fully qualified DN of the entry and deletes it from the
directory. The LDAP protocol allows only the leaf entries to be deleted. The modified
operation updates an existing entry. This operation takes the entry’s DN and a set of
modifications, such as adding a new attribute, updating a new one, or removing an
existing one. The rename operation can rename or move entries in a directory.
The authentication operations are used for connecting and ending sessions between
the client and the LDAP server. A bind operation initiates an LDAP session between the
client and server. Typically, this would result in an anonymous session. The client can
provide a DN and credentials to authenticate and create an authenticated session. On
the other hand, the unbind operation can be used to terminate an existing session and
disconnect from the server.
LDAP V3 introduced a framework for extending existing operations and adding new
ones without changing the protocol. You will take a look at these operations in Chapter 7.

Security Model
The LDAP Security model protects LDAP directory information from unauthorized
access. The model specifies which clients can access which parts of the directory and
what kinds of operations (search vs. update) are allowed.
The LDAP Security model is based on the client authenticating to the server.
As discussed earlier, this authentication process or bind operation involves the
client supplying a DN identifying itself and a password. An anonymous session is
established if the client does not provide a DN and password. RFC 282915 defines a

15
https://www.ietf.org/rfc/rfc2829.txt

12
Chapter 1 Introduction to LDAP

set of authentication methods that LDAP V3 servers must support. After successful
authentication, the access control models are consulted to determine whether the client
has sufficient privileges to do what is requested. Unfortunately, no standards exist for
access control models, and each vendor provides their implementations.

L DIF Format
The LDAP Data Interchange Format (LDIF) is a standard text-based format for
representing directory content and update requests. The LDIF format is defined in RFC
2849.16 LDIF files are typically used to export data from one directory server and import it
into another. It is also popular for archiving directory data and applying bulk updates to
a directory. You will use LDIF files to store your test data and refresh the directory server
between unit tests.
The basic format of an entry represented in LDIF is as follows:

#comment
dn: <distinguished name>
objectClass:  <object class>
objectClass:  <object class>
...
...
<attribute  type>: <attribute  value>
<attribute  type>: <attribute  value>
...

Lines in the LDIF file starting with a # character are considered comments. The dn
and at least one objectClass entry definition are considered required. Attributes are
represented as name/value pairs separated by a colon. Multiple attribute values are
specified in separate lines and will have the same attribute type. Since LDIF files are
purely text based, binary data needs to be Base64 encoded before it is stored as part of
the LDIF file.

16
https://www.ietf.org/rfc/rfc2849.txt

13
Chapter 1 Introduction to LDAP

Blank lines separate multiple entries in the same LDIF file. Listing 1-1 shows an
LDIF file with three employee entries. Notice that the cn attribute is multivalued and is
represented twice for each employee.

Listing 1-1. LDIF file with three employee entries

#  Barbara’s Entry
dn: cn=Barbara J Jensen,  dc=example, dc=com
#  multi valued attribute
cn: Barbara J Jensen
cn:  Babs Jensen
objectClass:  personsn: Jensen
#  Bjorn’s  Entry
dn: cn=Bjorn J Jensen,  dc=example, dc=com
cn: Bjorn J Jensen
cn:  Bjorn Jensen
objectClass:  person
sn: Jensen
#  Base64 encoded  JPEG  photo
jpegPhoto:: /9j/4AAQSkZJRgABAAAAAQABAAD/2wBDABALD
A4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQ ERXRTc4UG1RV19iZ2hnPk1xeXB
keFxlZ2P/2wBDARESEhgVG
#  Jennifer’s  Entry
dn: cn=Jennifer  J Jensen,  dc=example, dc=com
cn: Jennifer J Jensen
cn: Jennifer  Jensen
objectClass: person
sn: Jensen

L DAP History
LDAP was developed by Tim Howes, Steve Kille, and Wengyik Yeong to create a network
protocol to get data out. In 1993 appeared the first draft of the RFC 1487,17 which
contained the specification of LDAP based on the access of X.500.

17
https://datatracker.ietf.org/doc/html/rfc1487

14
Chapter 1 Introduction to LDAP

The first version acts as a proxy or gateway to X.500 directories, a comprehensive


directory service developed in the 1980s.
Tim Howes, with his colleagues, created the Open Source University of Michigan
LDAP Implementation, which became the reference for all the LDAP servers. The
project’s website is active18 and accessible only for historical reference.
The second version, the first to be operative (LDAPv2), was released in 1993 as an
Internet Engineering Task Force (IETF) Proposed Standard with basic operations like
searching and modifying information. This version offers limited functionality and has
some problems related to the security mechanisms.
The third version, the latest available, was released in 1997, including many
improvements related to security, like Transport Layer Security (TLS) and the possibility
of supporting referrals. It was based on RFCs like RFC 225119 and RFC 4519,20 which
explain the protocol and the supported data models. This version became the de facto
standard for directory services, and many applications have support to integrate and use
LDAP to obtain certain information.

LDAP Vendors
LDAP gained wide support from various vendors. There has also been a strong open
source movement to produce LDAP servers. Table 1-5 outlines some of the popular
directory servers and include the information about which is the docker image to run
each of them with a small configuration.

18
www.umich.edu/~dirsvcs/ldap/ldap.html
19
https://datatracker.ietf.org/doc/html/rfc2251
20
https://datatracker.ietf.org/doc/html/rfc4519

15
Chapter 1 Introduction to LDAP

Table 1-5. LDAP Vendors


Directory Vendor Open URL Docker Image
Name Source?

Apache DS Apache Yes https://directory.apache. https://hub.


org/apacheds/ docker.com/r/
openmicroscopy/
apacheds
OpenLDAP OpenLDAP Yes https://www.openldap.org/ https://hub.
docker.com/r/
bitnami/
openldap
Tivoli Directory IBM No https://www.ibm.com/docs/en/ No existing official
Server i/7.5?topic=services-tivoli- image; you need to
directory-server-i-ldap create one manually.
Active Directory Microsoft No https://learn.microsoft. No existing official
com/en-us/windows/win32/ image; you need to
adsi/so-what-is-active-direc create one manually.
tory?redirectedfrom=MSDN
eDirectory Novell No https://www.microfocus.com/ No existing official
en-us/cyberres/identity- image; you must
access-management/edirectory create one manually.
Oracle Directory Oracle No https://www.oracle. No existing official
Server (formerly com/security/identity- image; you need to
Enterprise Sun) management/technologies/ create one manually.
Edition (ODSEE) directory-server-
enterprise-edition
Oracle Internet No https://www.oracle.com/ No existing official
Directory (OID) middleware/technologies/ image; you need to
internet-directory.html create one manually.
OpenDJ ForgeRock Yes https://github.com/ https://hub.
OpenIdentityPlatform/ docker.com/r/
OpenDJ openidentity
platform/opendj
16
Chapter 1 Introduction to LDAP

ApacheDS and OpenDJ are pure Java implementations of LDAP directories. You
will be using these two servers for unit and integration testing of the code throughout
this book.

Sample Application
Throughout this book, you will be working with a directory for a hypothetical book
library. I have chosen the library because the concept is universal and easy to grasp. A
library usually stores books and other multimedia that patrons can borrow. Libraries
also employ people to take care of daily library operations. To keep things manageable,
the directory will not store book information. A relational database is suitable for
recording book information. Figure 1-7 shows the LDAP directory tree for our library
application.

Figure 1-7. Library DIT

I have used the RFC 224714 convention in this directory tree to name the base entry.
The base entry has two organizational unit entries that hold the employees’ and patrons’
information. The ou=employees part of the tree will hold all the library employee
entries. The ou=patrons part of the tree will hold the library patron entries. Both
library employee and patron entries are of the type inetOrgPerson objectClass. Both
employees and patrons access library applications using their unique login id. Thus, the
uid attribute will be used as the RDN for entries.

17
Chapter 1 Introduction to LDAP

Summary
LDAP and applications that interact with LDAP have become a key part of every
enterprise today. This chapter covered the basics of the LDAP directory. You learned that
LDAP stores information as entries. Each entry is made up of attributes that are simply
key-value pairs. These entries can be accessed via their distinguished names. You also
saw that LDAP directories have schemas that determine the type of information that can
be stored.
The next chapter will look at communicating with an LDAP directory using Java
Naming and Directory Interface (JNDI). In the chapters following Chapter 2, you will
focus on using Spring LDAP for developing LDAP applications.

18
CHAPTER 2

Java Support for LDAP


As the name suggests, the Java Naming and Directory Interface (JNDI) provides a
standardized programming interface for accessing naming and directory services. It
is a generic Application Programming Interface (API) that can access various systems,
including file systems, Enterprise Java Beans (EJB),1 Common Object Request Broker
Architecture (CORBA),2 and directory services such as the Network Information Service
and LDAP. JNDI’s abstractions to directory services can be viewed as similar to Java
Database Connectivity (JDBC)’s abstractions to relational databases.
The JNDI architecture consists of an Application Programming Interface or API and
a Service Provider Interface or SPI. Developers program their Java applications using the
JNDI API to access directory/naming services. Vendors implement the SPI with details that
deal with actual communication to their particular service/product. Such implementations
are referred to as service providers. Figure 2-1 shows the JNDI architecture and a few
naming and directory service providers. This pluggable architecture provides a consistent
programming model and prevents the need to learn a separate API for each product.

Figure 2-1. JNDI architecture

1
https://en.wikipedia.org/wiki/Jakarta_Enterprise_Beans
2
https://www.ibm.com/docs/en/sdk-java-technology/8?topic=orb-corba

19
© Balaji Varanasi and Andres Sacco 2023
B. Varanasi and A. Sacco, Practical Spring LDAP, https://doi.org/10.1007/979-8-8688-0002-3_2
Chapter 2 Java Support for LDAP

The JNDI has been part of the standard JDK distribution since Java version 1.3
and has not moved to Jakarta like other packages. The API itself is spread across five
packages:

• The javax.naming3 package contains classes and interfaces for


looking up and accessing objects in a naming service.

• The javax.naming.directory4 package contains classes and


interfaces that extend the core javax.naming package. These classes
can access directory services and perform advanced operations such
as filtered searching.

• The javax.naming.event5 package has functionality for event


notification when accessing naming and directory services.

• The javax.naming.ldap6 package contains classes and interfaces that


support the LDAP Version 3 controls and operations. Later chapters
will examine controls and operations.

• The javax.naming.ldap.spi7 package contains classes to support


defining custom DNS for LDAP. The support of this feature has
appeared since Java 12.

• The javax.naming.spi8 package contains the SPI interfaces and


classes. As mentioned earlier, service providers implement SPI, and
we will not cover these classes in this book.

3
https://docs.oracle.com/en/java/javase/21/docs/api/java.naming/javax/naming/
package-summary.html
4
https://docs.oracle.com/en/java/javase/21/docs/api/java.naming/javax/naming/
directory/package-summary.html
5
https://docs.oracle.com/en/java/javase/21/docs/api/java.naming/javax/naming/event/
package-summary.html
6
https://docs.oracle.com/en/java/javase/21/docs/api/java.naming/javax/naming/ldap/
package-summary.html
7
https://docs.oracle.com/en/java/javase/21/docs/api/java.naming/javax/naming/ldap/
spi/package-summary.html
8
https://docs.oracle.com/en/java/javase/21/docs/api/java.naming/javax/naming/spi/
package-summary.html

20
Chapter 2 Java Support for LDAP

LDAP Using JNDI


While JNDI allows access to a directory service, it is essential to remember that JNDI is
not a directory or a naming service. Thus, we need a running LDAP directory server to
access LDAP using JNDI.
Accessing LDAP using JNDI usually involves three steps:

• Connect to LDAP
• Perform LDAP operations

• Close the resources

Note Check if you have installed the correct version of Java on your machine.
To do this, look at Appendix A, which explains how to do it.
If you don’t have a test LDAP server available, please refer to the steps in Appendix
B for installing a local LDAP server or running it using Docker. The explanation
about how to install Docker and check if everything is okay appears in Appendix A.
This chapter aims to show how you can do different operations on LDAP using
Java without any framework. With this approach, you will see the complexity of
doing certain operations and writing many lines of code to do something simple
with the assistance of some framework like Spring LDAP.

Connect to LDAP
All the naming and directory operations using JNDI are performed relative to a context.
So the first step in using JNDI is to create a context that acts as a starting point on the
LDAP server. Such a context is referred to as an initial context. Once an initial context is
established, it can look up other contexts or add new objects.
The Context interface and InitialContext class in the javax.naming package can
be used for creating an initial naming context. Since we are dealing with a directory
here, we will use a more specific DirContext interface and its implementation
InitialDirContext. Both DirContext and InitialDirContext are available inside the
javax.naming.directory package. The directory context instances can be configured

21
Chapter 2 Java Support for LDAP

with properties that provide information about the LDAP server. The code in Listing 2-1
creates a context for an LDAP server running locally on port 1389.

Listing 2-1. How to create a basic connection with LDAP

Properties environment =  new  Properties();


environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.
ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://localhost:11389");
DirContext context  =  new  InitialDirContext(environment);

Note In the following parts of the chapter, I will explain in detail the most relevant
parts to connect and execute some operations to LDAP.
By the end of this chapter, you will see the different outputs of the execution of the
different methods.

In Listing 2-1, we have used the INITIAL_CONTEXT_FACTORY constant to specify


the service provider class that needs to be used. Here, we use the sun provider com.
sun.jndi.ldap.LdapCtxFactory, which is part of the standard JDK distribution. The
PROVIDER_URL is used to specify the fully qualified URL of the LDAP server. The URL
includes the protocol (LDAP for nonsecure or LDAPs for secure connections), the server
hostname, and the port.

Note The declaration of the type on a variable has been optional since


Java 14, so you don’t need to declare that the variable environment has the
type Properties; you can replace the keyword var, and the compiler will infer the
correct type.
This change does not add any feature related to the performance, so I decided to
keep the code simple.

22
Chapter 2 Java Support for LDAP

Once a connection to the LDAP server is established, the application can identify
itself by providing authentication information. Contexts like the one created in
Listing 2-1, where authentication information is not provided, are called anonymous
contexts. LDAP servers usually have ACLs (access list controls) that restrict operations
and information to certain accounts. So it is very common in enterprise applications to
create and use authenticated contexts. Listing 2-2 provides an example of creating an
authenticated context. Notice that we have used three additional properties to provide
the binding credentials. The SECURITY_AUTHENTICATION property is set to simple,
indicating that we will use a plain text username and password for authentication.

Listing 2-2. How to connect on LDAP using the credentials

Properties environment =  new  Properties();


environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.
ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://localhost:11389");
environment.setProperty(DirContext.SECURITY_AUTHENTICATION, "simple");
environment.setProperty(DirContext.SECURITY_PRINCIPAL, "Directory
Manager");
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "secret");
DirContext context  =  new  InitialDirContext(environment);

Note On the declaration of the different properties, you can see the class
DirContext appear many times, which is not the best approach, so if you want
to reduce the duplicates, you can simplify using static imports. For example, you
can declare the static import like this: import static ­javax.naming.directory.
DirContext.INITIAL_CONTEXT_FACTORY, and on the declaration of the variable,
just use PROVIDER_URL.

Any problems occurring during the context creation will be reported as instances
of javax.naming.NamingException. NamingException is the superclass of all the
exceptions thrown by the JNDI API. This is a checked exception and must be handled
properly for the code to compile. Table 2-1 lists common exceptions we will likely
encounter during JNDI development.

23
Chapter 2 Java Support for LDAP

Table 2-1. Common LDAP Exceptions


Exception Description

AttributeInUseException Thrown when an operation tries to add an existing attribute.


AttributeModificationException Thrown when an operation tries to add/remove/update an
attribute and violates the attribute’s schema or state. For
example, adding two values to a single-valued attribute would
result in this exception.
CommunicationException Thrown when an application fails to communicate (network
problems) with the LDAP server.
InvalidAttributesException Thrown when an operation tries to add or modify an attribute set
that has been specified incompletely or incorrectly. For example,
adding a new entry without specifying all the required attributes
would result in this exception.
InvalidAttributeValueException Thrown when an operation tries to add or modify a value of an
attribute that enters a conflict with the schema definition.
InvalidSearchFilterException Thrown when a search operation is given a malformed search
filter.
LimitExceededException Thrown when a search operation abruptly terminates as a user-
or system-specified result limit is reached.
NameAlreadyBoundException Thrown to indicate that an entry cannot be added as the
associated name is already bound to a different object.
NotContextException Thrown when an operation process until the context is required to
continue.
OperationNotSupportedException Thrown when a context implementation does not support a
specific operation when invoked.
PartialResultException Thrown to indicate that only a portion of the expected results is
returned and the operation cannot be completed.
SizeLimitExceededException Thrown when a method produces a result that exceeds a size-
related limit.
TimeLimitExceededException Thrown when a method produces a result that exceeds a time-
related limit.

24
Random documents with unrelated
content Scribd suggests to you:
I learnt afterwards that as the Shah, if he sits himself, is obliged to
give seats to the ambassadors, he avoided it by not sitting down, but
lounged in the manner described. There was nothing particularly
striking in the room; it was much over-decorated, and in the most
barbarous taste; the carpets, however, were valuable.
The ambassadors now all gave the king a military salute, and so
did the suites and hangers-on. To this his Majesty returned a not
over-gracious nod. The king now addressed them in turn, and each
ambassador replied through his dragoman or Oriental secretary,
replying to the questions as to his sovereign’s health, and
congratulating the Shah on his festival. Mr. Alison presented a new
secretary, and introduced Colonel G⸺, who was favourably
received, and in fluent and graceful Persian he replied to the Shah’s
queries, and made somewhat of a speech on telegraph matters,
which was also graciously received, the Shah assenting frequently.
The king now unceremoniously left the room, and every one saluted.
We all hurried off to see the great ceremony of the public salaam.
We were ushered pell-mell into a room that commanded on one side
the court of audience, on the other the public square of Teheran. In
the former were drawn up in rows, according to their degree, all the
officers of state, all the governors of provinces, all the generals and
servants of the Crown, the secretaries of various departments, and
the foreign employés, among whom I saw Mr. D⸺ and one of the
signallers, of the Telegraph Department.
We were told that in a few moments the Shah would lighten their
countenances by appearing in an open balcony above our heads.
The royal “farrashes,” or carpet-spreaders, armed with long wands
of unpeeled boughs, who surrounded the courtyard, began to beat
the few unauthorized onlookers at the far corners, and on a sudden
the whole crowd bowed nearly to the ground—a ceremony in which
the unfortunate Mr. D⸺ had to join nolens volens. This told us that
the king had shown himself.
The prostration was repeated a second and a third time. Then the
Prime Minister, having his rod of office, with many bows, mumbled a
speech to his Majesty; to which the king replied in a few words in a
loud voice.
A priest in a green turban (being a Syud or descendant of the
prophet) now recited what was apparently a long prayer: a dress of
honour on a tray was immediately, by the king’s order, produced, and
placed on his shoulders; and this was no empty compliment, for I
was told by an experienced onlooker that the cloak was worth one
hundred pounds or more.
Then a poet recited an ode, and got also a dress of honour; and
then, at the royal command, men bearing trays of gold coin
distributed handfuls to the officials, the number and size of the
handful being in proportion to rank; the bigger people, who stood in
the front ranks, getting the larger and more numerous handfuls.
Even Mr. D⸺, who was in a back row, got some seventy kerans
(three pounds). The coins were gold, and very thin, and are instituted
for this special occasion; they are called “shahis,” which is, literally,
“king’s money,” and were worth some one shilling and eightpence
each. During the excitement and scramble that the distribution
occasioned, the king retired, and the orderly ranks of Government
servants became at once a seething crowd.
We lookers-on now crossed the room and stood at a balcony
which commanded the public square. This was kept clear by a
double line of soldiers all in new clothes for the occasion. The space
was occupied by dancers, buffoons, jugglers, wrestlers, sword-and-
buckler men, and owners of fighting sheep and bulls, with their
animals; while in front of the big pond or hauz, immediately below
our balcony, stood twenty wretched Jews in rags and tatters,
prepared to be thrust head over heels into the water for the royal
delectation.
The king’s farrashes kept up showers of good-humoured blows on
an equally good-humoured crowd at all the entrances. Not less than
fourteen to sixteen thousand people were present; all were on the
tiptoe of expectation.
Suddenly a cannon from among a battery in the square was
discharged, and the king appeared. The entire crowd bowed to the
ground three times; then the people shouted and cheered, the
dancers went through their antics, the buffoons began their jokes,
some forty pairs of wrestlers struggled for mastery, among whom
was the king’s giant, seven feet eight inches high; gymnasts threw
up and caught huge clubs, and showed feats of strength and skill;
the swordsmen engaged in cut and thrust, hacking each other’s
bucklers; the jugglers showed their sleight of hand; the fighting bulls
and sheep rushed at each other; the royal bands and the regimental
ones struck up different tunes; the zambūreks (or camel artillery)
discharged their little cannon; the Jews were cast into the tank, and
on coming out were again thrown in by the farrashes and
executioners; while the rest of the cannon fired away merrily in every
direction; the bulls got among the crowd, the women shrieked and
the men shouted.
Handfuls of gold coin were thrown to the various performers, for
which they violently scrambled; and amidst the smoke and cries the
king retired.
The royal salaam was over, and we struggled through the crowd
within the palace to our horses at the gate, and rode home through a
happy mob, having assisted at a great Persian festival.
I dined at the Russian, English, and French embassies several
times at Teheran. As the entertainments were European there is
nothing to be described.
CHAPTER V.
HAMADAN.

Start for Hamadan—Bedding—Luggage makes the man—Stages—Meet Pierson


—Istikhbals—Badraghah—Pierson’s house—Hamadan wine—Mode of
storing it—My horses—Abu Saif Mirza—His stratagem—Disinterested
services—Persian logic—Pierson’s horse’s death—Horses put through their
paces—I buy Salts and Senna—The prince’s opinion—Money table—Edict.

A few days after the great festival Major S⸺, who was going
down country, kindly allowed me to accompany him as far as
Hamadan. We started one afternoon, doing the two first stages by
sunset, and stopping at the post-house at Karneabad.
The weather was fine, the roads and horses good. I had by this
time learnt to ride by balance only, and acquired the art of remaining
in an upright position on my steed whenever he suddenly dropped as
if shot, instead of going over his head by the force of momentum.
The Major had a few tinned provisions, which it had been impossible
to get in a place like Tiflis, and with a roast fowl or two our
commissariat was well provided. The intense cold was over, and I
was glad to use my goggles to protect my eyes during the middle of
the day. We also never started before the light was good, which
made an immense difference in our comfort.
I had invested in a native bridle, the severe bit of which enabled
me thoroughly to control my horses, and, being the one they were
used to, did not keep them in the perpetual state of fret that the
European bit did. My saddle-bags, too, were well packed and exactly
the same weight, so that I never had to get down to put them level,
and they never annoyed the horse.
I had my rugs, four in number, and the same size, sewn together
down one side and at the bottom, so that whichever side I might
have to the draught, and of this there is always plenty, I could have
one blanket under me, three over me, and the sewn edge to the
wind, while, as the bottom was sewn up, the blankets could never
shift, and the open side could be always kept to the wall. This
arrangement, an original one, I have never altered, for in hot
weather, by lying on say three blankets, one only was over me.
There is, however, one thing that I soon found out in travelling. To
thoroughly rest oneself it is needful to, firstly, undress and wear a
night-jacket and pyjamas; and, secondly, to sleep in a sheet. The
addition to one’s comfort is immense, particularly in warm weather,
while the extra weight of a sheet is not worth considering. An air
pillow, too, is a great luxury.
I have been in the habit of no longer using a waterproof sheet to
keep my blankets dry, but of rolling them tightly up, and then
strapping them and cramming them into an india-rubber soldier’s
hold-all, which ensures a dry bed, and straps handily to the saddle.
This hold-all was the cause of a rather amusing adventure.
On coming home once on leave, in a great hurry, I had left Persia
with only my hold-all, having given my saddle-bags and road kit to
my servant. I had come direct from Tzaritzin on the Volga to
Boulogne without stopping, but had to wait some hours on the tidal
boat before she started. I stepped on board and asked one of the
men where the steward was.
“Oh, he ain’t aboard yet, mate.”
“Can you get me a wash?”
“Come along a’ me, mate.” The man took me down to what
seemed the fo’cassel, and placed a bucket of water before me.
I said, “Come, is this the accommodation you give your first-class
passengers?”
The man roared with laughter.
“No yer doant, mate, no yer doant. I never seed no first-class
passengers with luggage like that,” pointing to my hold-all; and it was
only on producing my coupon book, that the man could be
persuaded I was not a deck passenger, and to take me to the saloon
aft.
As I was covered with coal dust, and generally grimy—the
opportunities for washing being then not what they are now in Russia
and Germany—the hold-all had made the man sure that I was an
impostor.
We came in the afternoon of the third day into Hamadan, having
done the stages in fair time. The journey was without incident, save
that a string of antelopes crossed the road in broad daylight some
ten yards ahead of us. As they appeared so suddenly, we neither of
us thought of using our revolvers. Hamadan looked pretty as we
entered it, and was surrounded by apparently interminable gardens.
On turning a corner we came upon Captain Pierson, under whom I
was to serve, and of whose division I was in medical charge. He had
ridden out to meet us.
In the early days of the Persian Telegraph it was usual to ride out
with the departing, and to do the same to meet the coming guest.
This is the Persian custom of the “istikhbal,” or ceremonious riding
out to meet the new arrival; being a very important ceremony,
regulated by hard-and-fast rules: such as that the greater the
personage, the further must the welcomer travel; while the lesser the
welcomer, the further must he go. Thus, in the case of a new
governor of Shiraz, the king’s son, the big men rode out three
stages, the ex-governor one, while some actually went as far as
Abadeh, or seven days’ journey; but these were mostly merchants or
small people.
Great fuss and parade is made, the condition of the incomer being
denoted by the grandeur of this “istikhbal,” or procession of
welcome. In the case of official personages, soldiers, both horse and
foot, go out; led-horses also are sent simply for show, splendidly
caparisoned with Cashmere shawls or embroidered housings on the
saddles. And it is found necessary, in the case of the arrival of
ambassadors or envoys, such as that of Sir F. Goldsmid (when on
the duty of the definition of the Seistan boundary), to stipulate that a
proper istikhbal shall be sent out prior to the commissioners entering
a large town.
There is another ceremony, that of the “badraghah,” or riding out
with the departing guest. This, however, is not so formal, and is less
an act of ceremony than one of friendship; however, it is a
compliment that in both cases is much appreciated, especially when
shown by a European to a native.
Latterly the Europeans have almost given up this riding out, which
practically is a great nuisance to those riding at an unusual or
uncomfortable time, perhaps in the sun, and when the arrival of the
guest is very uncertain; it is, too, very annoying, when tired with a
rapid chupper, and having ridden many hours on end, to be put on a
very lively horse, ready to jump out of his skin with condition, and to
pull one’s arms off.
As we had got in sooner than was expected, and were only some
mile from Pierson’s house, we did not change our horses for the
fresh ones provided by him, and after many turns and twists between
high mud walls, we came to the house, and here my travels ended
for the time.
The courtyard was some twenty yards by thirty wide. A hauz or
tank ran the entire length, filled by a constant stream of running
water, and on either side of it was a long flower-bed sunk in the
stone pavement, about the same depth below it as the hauz was
elevated above.
On a level with the ground in the basement were the cellars and
servants’ quarters, and above this a platform ten feet from the
ground, some four yards broad, which extended the whole width of
the courtyard. This was covered by an enormous structure,
consisting of a roof some six feet thick, being painted wood mudded
over a yard deep; and then under it a hollow air-chamber, supported
on three huge wooden octagonal columns, likewise painted in red,
blue, and yellow. Behind and beneath this talár, or verandah, which
was some thirty feet from floor to ceiling, was a central room
(orūssēe), elaborately painted and gilt in the vilest taste, with a huge
window (which could be kept wide open in hot weather) of coloured
glass, in small panes four inches by seven. This was the dining and
reception room.
On either side of this orūssēe, and having the talár still in front of
them, was a smaller apartment. One was Pierson’s bedroom, the
other mine. Thus in front of the three rooms was a covered platform,
four yards by twenty. On this during the summer, save when the sun
was on it, we lived, and when the sun was high the rooms were kept
cool by the talár.
We soon sat down to a sumptuous dinner, and I tasted, for the first
time, Hamadan wine, of which I had heard many and different
opinions. It was a delicious pale, scented, straw-coloured wine, like a
light hock; rather too sweet, but apparently of no great strength. I
soon found, however, that in the latter idea I was much in error, for it
was a wine that went straight to the head, and remained there.
Delicious as it is, the fact of its newness—and it often will not
keep, a second summer generally turning it sour if in bottle—makes
it objectionable, for though it is light and delightful, especially when
iced, a headache surely follows even a third glass.
The natives, we found out in after years, are able to keep it in bulk,
and then the tendency to give an after headache goes away, but so
does the delicious flavour. In winter so cold is Hamadan, that the
wine, which is kept in huge jars holding two hundred maunds (or
eight hundred bottles), or even more, sunk half their depth in the
ground, has to be kept from freezing by making a hot-bed of
fermenting horse-dung around the upper part of these jars, and often
these means fail; for I have myself been present when blocks of
frozen wine have been chopped out of the jars for drinking; these
plans of storing wine only refer to Hamadan: in other Persian towns
the wine, as soon as it is cleared, is placed in carboys, holding from
six to twenty-four bottles.
It is sold in Hamadan in baghallis, or native bottles, holding about
a pint and a half. They are of the very thinnest glass, and very fragile
when empty. One of these bottlefuls costs about fourpence—at least
it did when I was in Hamadan in 1869.
In a couple of days Major S⸺ left on his way to Baghdad, and
Pierson insisted on my remaining his guest, which I was only too
glad to do, till I could get servants, etc. of my own.
The first thing, however, was to buy a horse, as I could not draw
my horse allowance from Government till I had really a horse of my
own, and the three pounds a month was, considering the smallness
of my pay, a consideration. Of course at that time I knew nothing
about horses, and was fortunate in having the advice of Pierson. As
soon as it was given out that I wanted horses there was a permanent
levée at our quarters of all the owners of the lame, the halt and the
blind, and their animals. These men, however, were all sent to the
right-about by Pierson, and at last a dealer came with four likely
young horses; these were examined and pronounced sound. On
their price being asked, one hundred tomans each was demanded. I
was disappointed, for this was exactly the sum (forty pounds) that I
was prepared to give for two horses. But I was reassured by Pierson,
who made me understand that that was always the price asked for
any beast worth having, and merely meant that the seller did not
mean to take less than one half the amount. I was told, too, that if
one wanted to buy a horse anywhere near its value some weeks
must be taken in the negotiation. The matter ended in Pierson’s
offering the dealer fifty tomans for two of the animals, and the man
leaving our courtyard in simulated indignation, declining even to
notice a bid so ridiculous. However, as Pierson said we had not seen
the last of him, I did not despair.
Next morning, on coming out to breakfast, I saw our horse-dealer
seated with the servants, and as Pierson put it, “They are settling the
amount of commission they are each to get, and this commission
they will have; ten per cent. is legitimate, more is robbery. So all we
have to do is to be very determined; if you can get any two of the
four animals for your limit you will do well, if not you must let them
go.”
Pierson now sent for his head-man and told him that “I was to
have two serviceable horses for forty pounds, and that I should not
pay a penny more; so, as he knew the amount of modakel (profit) he
and the rest of the servants could make, he had better do the best
he could for me, and that he (Pierson) would see that I was not done
as to quality.” The man cast up his eyes and retired.
While we were at breakfast a poor prince, Abu Saif Mirza, came,
and was invited to partake. Pierson told me that he was a very good
fellow indeed, and a grandson of Futteh-Ali Shah,[7] a former Shah
of Persia, but from the irregularity with which his very small pension
was paid, he had to live almost by his gun, and chance meals, such
as the present.
Of course I could not understand what he said, but he fully entered
into the difficulty as to finding me a horse. And as in Persia nothing
can be done without stratagem, he suggested on the spot a means
for bringing the dealer to his senses; it was deep, “deep as the deep
blue sea.” It was simply this: he would exhibit his horse to Pierson
and promise to send it for trial to-morrow, naming a price just about
its value, and “then you will see all will be well.”
No sooner was breakfast over than the prince’s horse was brought
into the courtyard, stripped and examined, and the suggested
arrangement made. As it happened I afterwards bought this very
horse for Pierson to make a wedding present of, but he would have
been more than I could manage at the time, being a spirited beast
and a puller. The Shahzadeh (prince) took his departure, promising
loudly to send his horse round in the morning.
No sooner was he gone than the nazir, or head-servant, presented
himself and delivered to Pierson an oration somewhat of this sort.
“May I represent to the service of the sahib, that it would be very
unwise to purchase the horse of the prince? he is not young” (he
was five years old), “he is gone in the wind” (he was quite sound),
“and his temper is awful; besides this I have reason to know that he
is worthless in every respect” (he was one of the best horses I ever
saw, and I knew him for ten years). “Of course to me it would make a
great difference, for the prince has indeed offered me a handsome
commission” (quite untrue), “while from this poor dealer not a
farthing can be wrung by the servants. No! he would rather die than
pay one farthing. So though the other servants are loath to let a sale
take place to my sahib’s friend, yet I, as an old servant, and looking
for a reward from my sahib for conduct so disinterested, have after
infinite trouble got the dealer to consent to a hundred and fifty
tomans for any two of his four horses.”
“Be off,” was the laconic reply of Pierson. “When we ride to-day, if
the dealer will sell for my price, let the horses be ready and I will see
them and ride them; if not he can go.”
The man sighed and replied: “Ah, I see, sahib, the prince has
laughed at your beard, and persuaded you to buy his worthless
brute. I can’t offer such terms to a respectable man like the dealer,
but I will give the message.”
I now saw the horse-dealer leave the courtyard with the air of an
injured man, and I feared I was as far off a purchase as ever. But
Pierson reassured me. I had plagued him to sell me one of his own
large stud which he wished to reduce, but he declined with a smile,
saying he never sold a horse to a friend unless he was a thorough
judge, and that as I knew nothing about horses he must decline, as I
might repent when too late; and though I pressed him a good deal,
he would not relent. Few men would have lost an opportunity to get
rid of beasts they did not require, but Pierson was a man in a
thousand.
At that time he had eight horses in his stable, all good and all
sound. He had named them after heathen gods, Jupiter, Pluto,
Saturn, Cupid, Hercules, etc. But his pet nag, Apollo—a grey he had
given one hundred and twenty tomans, or fifty pounds, for, an
enormous price in those days in Persia—had a few weeks before
caught his foot in a hole while galloping over turf; horse and man
came down with a crash; Pierson was insensible; and when he came
to himself he found, some four yards off, his favourite lying dead with
his neck broken.
He rode away on his groom’s horse, the man carrying his saddle
and bridle. On getting to the house he sent a gang to bury the poor
beast, but too late, for the villagers had taken off the skin and tail.
Pierson on telling me the story did it so pathetically, that he left off
with wet eyes, and I felt inclined to sob myself.
As we got ready for the afternoon ride, the horse-dealer and his
four horses appeared, and with a sigh he informed Pierson that he
accepted the terms, or nearly so. On getting out of the town the
horses were put through their paces. They were a big grey, with
enormous mane and tail, of not much breed, but in dealer’s
condition, and a well-shaped and strong-looking beast; an iron-grey,
who plunged and shied and was generally vicious, but really the
most valuable of the four; a fourteen-hand pure-bred Arab, with a
huge scar of a spear-wound a foot long on his shoulder, otherwise
perfect, of angelic temper, but small by the side of the Persian
horses, as all Arabs are; his muzzle almost touched his chest as he
arched his neck, and his action was very high, yet easy; he seemed
an aristocrat compared to the rest; his thin and fine mane and tail
were like silk—he, too, was five. A big, coarse, raking chestnut, that
took all the boy who rode him could do to hold him, rising four,
completed the list.
Pierson kindly rode them all, and with considerable fear I did the
same, save the lively grey, which I wisely acknowledged to be too
much for me. The big chestnut bolted with me, but I stuck on. The
other chestnut was all I could wish, fast, paces good, no tricks,
willing—but, then, the scar. I did not wish to buy him on that account,
but Pierson over-ruled me, and I took his advice; he told me that in
Persia a scar was nothing, that I could ride the horse in comfort and
safety, as he had no vices, and that whenever I wished to sell I
should lose very little. The raking chestnut, as a young horse,
Pierson told me was a speculation; he might turn out well, he might
not. And the grey—well, all I could get out of Pierson was, that “he
had a fine mane and tail,” which he certainly had, and that “he was
value, or nearly.” He was not a well-bred animal, and I liked him, I
fear, on account of the mane and tail; but he pulled. All were entire
horses.
Pierson wouldn’t let me buy the iron-grey, had I wanted to, as he
said he was dangerous, even to a good rider.
So the matter ended in my taking the chestnut for five hundred
and fifty kerans and the grey for six hundred and fifty. Pierson said
the prices ought to have been reversed. He was right. I had that
chestnut Arab ten years; he never was sick or sorry, and I never had
to strike or spur him; a pressure of the knee and a shake of the rein
would make him do his utmost. And he was a fast horse; small as he
was he carried my twelve stone comfortably, and as a ladies’ horse
he was perfect, having a beautiful mouth, while he followed like a
dog, and nothing startled him or made him shy. In the stable he was
quiet, save to a new-comer, on whom he always left his mark by a
bite on the neck, and then, having asserted his position, which was
afterwards never disputed, he was always friendly to stable
companions. He never kicked. I gave him away at last, when I left
Persia on leave.
Next morning the “poor prince” called and looked over my
purchases; he approved the chestnut, but shook his head at the
grey, saying he had “ableh,” or leprosy, and that in time he would
break down, pine, and die. The only sign he had was a pink patch
the size of a fourpenny-piece on his black muzzle. “Give him back,”
said the Prince.
“I can’t see anything wrong,” said Pierson. His mane and tail
decided me. I stuck to him, christening him “Salts”—the chestnut I
called “Senna.”
The custom in Persia is that, until a horse has been three nights
fed in the stable of a new master (unless specially stipulated to the
contrary before witnesses of respectability, or in writing) he may be
returned without giving any reason whatever, simply on the
purchaser repenting his bargain; this is often taken advantage of by
the buyer to return the animal in order to lower his price; the
manœuvre seldom succeeds, as the seller is prepared for it.
The European, if awake to his own interest, generally spends the
three days in giving the beast a good “bucketting” over ploughed
land, when, if there be any hidden defect, it comes out, and the
animal can be returned. We did this, but no fault showing itself, I paid
my one hundred and twenty tomans[8] (forty-eight pounds) and
concluded the purchase.
CHAPTER VI.
HAMADAN.

Morning rides—Engage servants—Dispensary—A bear-garden—Odd complaints


—My servants get rich—Modakel—The distinction between picking and
stealing—Servants—Their pay—Vails—Hakim Bashi—Delleh—Quinine—
Discipline—I commence the cornet—The result of rivalry—Syud Houssein—
Armenians—Cavalry officer—Claim to sanctity of the Armenians—Their
position in the country—Jews.

As the weather got warmer we began morning rides; we used to


start regularly at six A.M. Pierson kindly gave me a hint occasionally,
and we had some very enjoyable canters about Hamadan, the
environs of which are very pretty and full of foliage; in this other
Persian towns are generally rather deficient. We usually managed to
get in before the sun got too high, had a second tub, and dressed for
breakfast.
I engaged three servants, Abdul-Mahomed, personal or head-
servant; Abdullah, a groom-boy; and Ramazan, as sweeper and
dispensary attendant.
As the staff under my official charge was very small, and they were
unmarried healthy men, my Government work was very trifling; but a
constant crowd at the door, desirous of seeing the new Hakim,[9]
made me anxious to take the advice given me while in Teheran, and
make the most of my opportunities ere the novelty had worn off. I
gave out, then, that I was prepared to see patients from eleven A.M.,
and a courtyard that we did not use in any way, (it was originally the
women’s quarter of our house,) was kindly placed at my disposal by
Pierson, who also gave me the advantage of his knowledge of
Persian as an interpreter.
I saw my servant was very busy indeed, and that all the morning a
file of people were flocking into the courtyard, in which I had installed
my dispensary. Precisely at eleven I proceeded to seat myself; what
was my astonishment to find some two hundred people sitting in
groups, my two servants vainly endeavouring to keep some sort of
order; the noise was great, and practical joking and laughter were in
the ascendant.
Pierson’s presence, however, awed the rioters, and silence was
after a time obtained, some few of the more noisy among the males
being ejected.
I soon found that many of the so-called patients had merely come
from curiosity, while others had old injuries to complain of, and did
not expect medicines, but miracles.
The replies to the question, “What is the matter?” were sometimes
highly ridiculous, one man informing me that he had a serpent in his
inside, while another complained of being bewitched.
Among the ladies, Pierson, who bravely stuck to his self-imposed
duty of interpreter, informed me that the principal request was for
aphrodisiacs, drugs to increase embonpoint, and cosmetics; while
many women of apparently great age were urgent for physic for
improving their appearance. Many cases of eye-disease presented
themselves, and not a few of surgical injury, which had been treated
only in the most primitive manner. It was only by four in the afternoon
that I succeeded in getting rid of the rabble-rout that had come to my
dispensary.
Rome was not built in a day. As the novelty wore off and the
sightseers ceased to come, the sick, who generally amounted to
from two hundred to two hundred and fifty a day, more or less,
became more tractable, and my servants better able to manage
them.
I made stringent rules as to seeing all in the order of their coming,
and separating the men from the women. Although I saw many
thousands of patients in Hamadan, yet I found that I made no
appreciable addition to my income; those who could pay, didn’t; and
the only grist that came to the mill my two men absorbed. These now
bloomed out in silken raiment, and my head-man, whose pay was
twelve pounds a year, and clothe and feed himself, actually kept a
servant of his own, and adopted a slow and dignified pace, which, as
he day by day increased in wealth, became more and more
apparent.
I, after some weeks, on some provocation or other, determined to
discharge Ramazan, who immediately told me, with many
protestations, that on account of the great love he bore me he could
not leave me, and was desirous to stay at half-wages. On my
remaining obdurate he wished to stop on nothing a month and “find
himself.” He begged so hard that I couldn’t turn him out, and forgave
him. The fact was, that his pickings from the daily crowd of patients
was some ten times as much as his pay.
Often have I been asked by Persian acquaintances, “What is your
pay?” “Little enough,” I reply. “Ah, but what is your modakel?” i. e.
pickings and stealings.
This system of modakel it is useless to fight against. The Persians,
from the king downwards, speak of “my modakel.” The governor of a
province buys his appointment: this is the king’s modakel; he farms
the taxes for one hundred thousand tomans, and sells them for half
as much again; this is his modakel; the buyer exacts two hundred
thousand, the difference is his modakel.
I buy a horse, a carpet, or a pound of sugar, ten per cent. is added
by my servant to my bill. I sell a horse, and ten per cent. is taken on
the price by my servant. I pay a muleteer, and ten per cent. is
deducted from the hire. These things are the so-called legitimate
“modakel” of my servant, and I cannot avoid it. If pressed, or the
thing is brought home to him, he will not even hesitate to
acknowledge it.
“It is the custom, sahib. Could you have bought the thing cheaper
than I, or sold it so well, even with the modakel? No, you could not;
then why object? What stimulates me to do the best I can for you?
My modakel; you cannot fight against it.” And he is right; the ten per
cent. is extracted from all, Europeans or Persians; and it is no use to
kick against the pricks. But more than this is considered robbery (if
detected).[10]
In the last five years of my life in Persia I kept all these servants
mentioned in the note, with the exception of a nazir, who is, as a
rule, a purely useless man, and only an increaser of his master’s
expenses for the sake of the addition to his own profits. Thus my
cook, through whose hands the whole expenses, eight hundred
kerans a month, or at times a thousand, used to pass, made, say,
ninety kerans as his percentage; out of the sums paid for shoeing
and repairs and sale of manure (a valuable perquisite), the grooms
made theirs; while for every penny expended by my servant a
percentage was taken in money or goods.
Even the laundress would take (not steal) a tenth or more of the
soap given her. But then it was no use fighting against it, for it was
not etiquette for the better-class European to be seen in the bazaar,
save for special things, as curios, and such a proceeding would
entail a great loss of consideration, and cause him to be classed as
a “mean white.”
Again, one’s head-servant, though he took this percentage, made
it a point of honour to do his best for you after that had been
deducted, and no one else but himself was permitted to rob on a
large scale.
I have struggled against the system repeatedly. I have even
caused muleteers to be paid in my presence, and have given them a
present for civility, and have then ordered the men off the premises,
not allowing my servants to leave the house; or I have paid by
cheque on a native banker; but I am sure the servants got their
commission, and shared it in certain proportions arranged among
themselves.
Another source of revenue to servants is the system of vails. This
is, I am glad to say, being lessened. At one time the Europeans
encouraged it. I remember, after I had been about a year in the
country, going to stay with Pierson in Teheran, on a visit of five
weeks: I gave his head-servant to distribute amongst the rest two
hundred and fifty kerans, or ten pounds. The man’s face did not
express a lively satisfaction, though that was merely policy; and as I
was riding out of the gate, the “dog-boy,” a youth retained to feed the
five or six dogs my friend kept, seized my bridle, and asked me
roughly, “Where was his present?” This was more than mortal man
could stand; I thonged the fellow, going back afterwards to explain
and apologise to his master, who turned him out then and there.
Thus a servant, though he nominally feeds and clothes himself,
has his wages, his profits, his presents which each servant gets from
his master at the New Year—generally a month’s pay—his vails, and
his master’s old clothes; as these fetch a high price in a bazaar, they
are an important item in the servant’s budget. In addition to this, he
gets a small allowance when travelling, and on the road his master
feeds him. So that, taken altogether, his position is not a bad one,
the emoluments of my head-man, for instance, being more than
those of a native country doctor in fair practice.
I felt considerable satisfaction at this time at the visits to my
dispensary of the “hakim bashi” (chief doctor), or rather one of those
who had that title in Hamadan. He expressed himself as eager to
learn, and knew a few words of French. I was, of course, delighted to
give him any information I could, and he seemed very grateful for
instruction; he, however, turned out afterwards to be a wolf in
sheep’s clothing, and was very nearly the cause of my stay in Persia
being brought to an abrupt termination, a matter which will be duly
detailed.
One day one of the servants brought a “delleh”[11] for sale, a sort
of weasel, and of similar size; he was of an olive-green colour, with a
bushy tail, having patches of yellowish-white on the body: a boy
dragged him in by a string. He was so fierce no one would go near
him, and was evidently carnivorous.
He was kept on our platform tied to a ring, till one day he gnawed
his thong and bolted into a hole. In this hole he remained, just
showing his nose in the daytime, but coming out at night, when he
was generally pursued by our dogs, who roamed about the place
loose.
I had been in the habit of feeding the beast on raw meat, of which
he was immoderately fond, and after some little trouble I taught him
to come to call. The animal got very tame, though extremely
pugnacious when teased, bristling his long soft fur out, like the
mongoose, biting savagely, and emitting a short sharp cry of rage.
He used to beg for his food, sit in our hands, allow himself to be
stroked, and became a great pet with both of us; but, as he showed
a great disinclination to be tied up, we allowed him to live in his hole
in the wall. As he grew fat from good living, he discontinued his
nocturnal excursions, presenting himself at meals with great
regularity; his intelligence was great, and the servants, who hated
him, and looked on him as “nejis,” or unclean, kept carefully out of
his way; as did the dogs, most of whom had been bitten severely,
and the suddenness of his movements and the sharpness of his
cries terrified them.
The beast, too, had another mode of defending himself, which I
am glad to say he only resorted to once when hard pressed. Two of
the dogs had got him in a corner, when suddenly they both bolted,
and the delleh made for his hole in a dignified manner. He had
employed the mode of defence used by the skunk, and the particular
corner of the courtyard, and the two dogs and the delleh were
unapproachable for a fortnight.
However, the animal had no stronger odour than any other
carnivorous beast, save on this occasion, and it probably was his
only means of safety. After he had inhabited his hole some months,
while he was gambolling on our platform, I saw the head of a second
delleh cautiously protruded and rapidly withdrawn. He had been
joined by a female, and after a week or two, she too became quite
tame. Like the ferret and mongoose, these animals waged war
against whatever had life, hunting fowls, etc., with the peculiarly
stealthy gait so well known.
I noticed now that a considerable number of my patients, and
Persian acquaintances, and all the servants, were continually
pestering me for quinine. The reason was that the high price of this
drug, pure as I had it, was a temptation, and as each impostor got a
small quantity, my store sensibly diminished.
I was loath to stop distributing the drug altogether, as I had been
particularly instructed that the giving away of quinine to the sick was
beneficial, indirectly, to the good feeling which we desired to produce
towards the English in Persia.
However, I made a rule only to give away the drug in solution, or,
in the case of servants of our own, in the dry state in the mouth.
This had the desired effect, and as a rule one dose of the bitter
drug caused the most grasping of the domestics to hesitate before
applying for a second. This system I adopted during the whole time I
was in the country, only giving the crystals to the European staff, and
the quinine being distributed each year in ounces, where before it
had been pounds. In fact, I did away with one of the sources of
legitimate (?) modakel of the servants, who had traded on my
innocence and simulated fever (intermittent) to obtain what was such
very “portable property.”
One morning, while we were at breakfast under the “talar,” we saw
a European enter the compound, and a little scene ensued that was
sufficiently amusing. I must premise that in those early days of the
Persian Telegraph Department, when communication was
infrequent, owing to the continual destruction of the line, orders could
only be conveyed by letters, which often never reached their
destination.
The unknown sahib, without announcing himself, or asking if the
superintendent were visible, stalked up on to the platform and thrust
a paper into Pierson’s hand. On it was an order to Mr. P⸺ to
proceed to Hamadan and take charge of the office there. And he (Mr.
P⸺) had that moment alighted from his horse, having marched
some twelve stages from Ispahan.
Pierson took the paper, read it, and said, “Well?”
The stranger replied, “I’m P⸺.”
“Have you nothing else to say?” said Pierson.
“No; I’ve come to take charge of the office here.”
Pierson now called for ink, and wrote “Mr. P⸺ will proceed at
once to Shiraz, and take charge of the office there,” and signed it.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookmass.com

You might also like