summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-10 15:34:36 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-10 15:34:36 -0400
commit84f52c6115c570ca2299f358d9d5dd9be2b24266 (patch)
treec2baf6839162ec74b5fc447fad79c0c8817f6643
parentcd01310f5f0ef8626e745956d93e3ef5b6becb3d (diff)
downloadslapi-nis-84f52c6115c570ca2299f358d9d5dd9be2b24266.tar.gz
slapi-nis-84f52c6115c570ca2299f358d9d5dd9be2b24266.tar.xz
slapi-nis-84f52c6115c570ca2299f358d9d5dd9be2b24266.zip
- updates
-rw-r--r--doc/design.txt101
1 files changed, 60 insertions, 41 deletions
diff --git a/doc/design.txt b/doc/design.txt
index 1bbbbfc..e01e2e8 100644
--- a/doc/design.txt
+++ b/doc/design.txt
@@ -7,7 +7,7 @@ correspond to the contents of maps, reads the contents of various
attributes from those entries, and uses that data to synthesize entries
for maps which it serves to clients.
-In broad strokes, it might look like this:
+In broad strokes, one design might look like this:
┌──────────┐ NIS ┌───────────┐ LDAP ┌────────────────────┐
│ Client │─────────│ Gateway │──────────│ Directory Server │
@@ -37,7 +37,7 @@ diagram, and breaking them down further, we can come to this:
│ NIS Protocol │───│ Mapping │───│ Directory Server Back Ends │
└──────────────┘ └─────────┘ └────────────────────────────┘
-The links in this diagram are all API calls. We've relegated the work
+The links in this diagram are now API calls. We've relegated the work
of reading a query (parsed from the NIS client by the NIS Protocol
handler), converting that query to a directory server search operation,
and marshalling the results of that search into a format suitable for
@@ -48,18 +48,18 @@ This approach does have its problems, though.
NIS, as a protocol, requires that the server be able to supply a few
bits of information which can't readily (or shouldn't) be retrieved this
-way.
+way, information which is not normally kept in a directory server.
NIS requires that a server be able to report a revision number for a
-map, akin to the serial number used in a DNS SOA record. A slave server
-can use this information to poll for changes in map contents on the
-master, possibly beginning a full map enumeration to read those new
-contents in order to serve its clients.
+map, which is used as an indicator of the time when the map was last
+modified. A slave server can use this information to poll for changes
+in map contents on the master, possibly beginning a full map enumeration
+to read those new contents in order to serve its clients.
A directory server, if it stores revision information at all, stores
it on a per-entry basis. So when a gateway designed as we diagrammed
above is asked for this information, it has at least these options:
- a) use an ever-increasing value, such as the current time
+ a) always use the current time
- This causes frequent map updates on clients when they don't need
them, and completely unnecessary network traffic.
b) always use the same value
@@ -67,13 +67,14 @@ above is asked for this information, it has at least these options:
c) return the latest revision of any of the results which formed the
contents of the map
- This could severely load a directory server if the information
- needs to be generated dynamically and frequently.
+ needs to be generated by reading the last-modified timestamps
+ from many directory server entries.
NIS also requires that a server be able to answer whether or not it
services a specified domain, and which maps it serves for a domain that
it serves. While the mapping module could search the directory's
configuration space whenever it is asked these questions, the first
-question is asked repeatedly by each running copy of ypbind, which could
+question is asked regularly by each running copy of ypbind, which could
also bog servers down (though admittedly, less than the previous case).
If we break the mapping portion up further, we can introduce a map
@@ -87,9 +88,10 @@ using data from the cache.
└──────────────┘ └───────────┘ └──────────────┘ └──────┘
Which takes us to the current design. The NIS protocol handler reads
-data from the map cache, and the map back end uses SLAPI to populate the
-map cache at startup-time, as well as to watch for changes in the
-directory's contents which would need to be reflected in the map cache.
+data from the map cache, and the map back end uses SLAPI to obtain data
+which is used to populate the map cache at startup-time, as well as to
+watch for changes in the directory's contents which would need to be
+reflected in the map cache.
=== Components ===
@@ -102,36 +104,49 @@ server has not yet dropped privileges, and the portmapper will not allow
registrations to unprivileged clients.) The plugin then starts a
listening thread to handle its clients.
-The plugin listens for datagram queries from clients, processing them
-as they come in, as well as answering connections from clients.
-Because connected clients may not always transmit an entire request at
-once, and because the server may find itself unable to transmit an
-entire response at once, it buffers traffic for connected clients,
-multiplexing the work it does for all of its clients from inside of the
-thread. The actual protocol datagram parsing is performed by libnsl,
-which is provided as a part of the C library.
-
-Client requests are limited by the local tcp_wrappers configuration on
-the directory server.
-
-Access control can be performed based on a client's address using
-"nis-plugin-securenet" settings in the module's configuration entry.
-If no values are specified, access is allowed to all clients. If values
-in the form "netmask address" (for example, "255.0.0.0 127.0.0.0") are
-found, then access will only be allowed to clients on the designated
-networks.
+The plugin listens for datagram queries from clients, processing them as
+they come in, as well as answering connections from clients. Because
+connected clients may not always transmit an entire request at once, and
+because the server may find itself unable to transmit an entire response
+at once, it buffers traffic for connected clients, multiplexing the work
+it does for all of its clients from inside of the single thread. The
+actual protocol datagram parsing is performed by libnsl, which is
+provided as a part of the C library.
+
+Client access is limited by the local tcp_wrappers configuration on the
+directory server, with a tcp_wrappers service name as dictated by the
+plugin's configuration.
+
+Client requests are also limited based on a client's address using
+"securenet"-style settings in the module's configuration entry. If no
+values are specified, access is allowed to all clients.
+
+Client requests are further classed as "secure" or not, based on the
+query's originating port. This information is used elsewhere for
+additional access control.
+
+== NIS Layer ==
+
+The NIS layer processes complete requests, whether they come in from
+connected or datagram clients, fetches the requested information from
+the map cache, and uses callbacks provided by the protocol handler to
+respond. Before doing so, if a value is being retrieved from a map, it
+checks if the map's contents are restricted to "secure" clients. If
+they are, but the client is not a "secure" client, the NIS layer will
+respond as if no data were present in the map.
== Map Cache ==
The map cache keeps a dynamically-constructed set of maps in memory,
grouped by domain, and for each map maintains information regarding the
last time its contents were modified (to answer client requests for a
-map's order). The map cache can quickly answer whether or not a domain
-is being served by checking whether or not any maps are defined for it.
-The definitions of which maps are served for which domains is
+map's order) and whether or not the map's contents should be restricted
+to "secure" clients. The map cache can quickly answer whether or not a
+domain is being served by checking whether or not any maps are defined
+for it. The definitions of which maps are served for which domains is
configurable via internal APIs -- the map cache itself has no forehand
knowledge of domain names, map names, or formats, as it merely models
-data in the way that a NIS server might.
+data in the way that a conventional NIS server might.
Forcing queries to use the cache provides a couple of benefits over an
alternate approach of performing an LDAP query for each NIS query:
@@ -139,8 +154,8 @@ alternate approach of performing an LDAP query for each NIS query:
server can be case-sensitive, which is preferred by NIS clients and
a requirement for some customers.
* Because the query used is never used to construct an LDAP filter or
- query, we don't have to worry about escaping text to avoid string injection
- attacks.
+ query, we don't have to worry about escaping text to avoid string
+ injection attacks.
== Back End ==
@@ -159,11 +174,11 @@ cache from its configuration area in the directory server. Beneath the
plugin's entry, the backend checks for entries with these attributes:
* domain
* map
+ * secure
* base
* filter
* keyFormat
* valueFormat
- * secure
The backend then instructs the map cache to prepare to hold a map in the
given domain with the given map name, and then performs a subtree search
under the specified base for entries which match the provided filter.
@@ -172,12 +187,14 @@ stored in "keyFormat" to construct the key for the entry in the map,
with the corresponding value in the map being constructed using the
format specifier given as the "valueFormat".
+== Formatting Data for NIS ==
+
The "valueFormat" specifier resembles an RPM format specifier, and can
include the values of multiple attributes in any part of the specifier.
The backend composes the string using the attribute values stored in
the directory server entry, using the format specifier as a guide. In
this way, the NIS map's contents can be constructed to almost any
-specification, can make use of data stored using any schema.
+specification, and can make use of data stored using any schema.
An example specification for the value for a user's entry could look
something like this:
@@ -186,8 +203,10 @@ The syntax borrows from RPM's syntax, which in turn borrows from shell
syntax, to allow the specification of alternate values to be used when
the directory server entry doesn't include a "userPassword" or "gecos"
attribute. Additional operators include "#", "##", "%", "%%", "/",
-"//", which operate in ways similar to their shell counterparts, and
-"!", which rejects values containing any characters which follow it.
+"//", which operate in ways similar to their shell counterparts (with
+one notable exception being that patterns for the "/" operator can not
+currently be anchored to the beginning or end of the string), and "!",
+which rejects values containing any characters which follow it.
To ensure safety, any reference to an attribute value which does not
also specify an alternate value will cause the directory server entry