Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/HACKING
blob: 84a86d34350e2940a8f3b24020fb4d545417b983 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

This document tries to describe the software layout and design of
nss-pam-ldapd. It should provide some help for contributing code to this
package.

CONTRIBUTING TO NSS-PAM-LDAPD
=============================

Contributions to nss-pam-ldapd are most welcome. Integrating contributions
will be done on a best-effort basis and can be made easier if the following
are considered:

* for large changes it is a good idea to send an email first
* send your patches in unified diff (diff -u) format
* try to use the svn version of the software to develop the patch
* clearly state which problem you're trying to solve and how this is
  accomplished
* please follow the existing coding conventions
* please test the patch and include information on testing with the patch
  (platforms tested, etc)
* contributions will be acknowledged in the AUTHORS file
* include a copyright statement in the patched code if you feel the
  contribution is significant enough (e.g. more than a few lines)
* when including third-party code, retain copyright information (copyright
  holder and license) and ensure that the license is LGPL compatible

Please email nss-pam-ldapd-users@lists.arthurdejong.org if you want to
contribute.


BUILD DEPENDENCIES
==================

For building svn snapshots the following tools are needed:

* autoconf (2.61 is used but 2.59 is minimal)
* automake (1.11 is used)

and of course the usual build tools (gcc/make/etc). Also see debian/control
(Build-Depends field) for libraries you may need.

To build the svn snapshot run the autogen.sh shell script to build the
configure script. When developing patches please use --enable-warnings with
configure and don't introduce too many new warnings. For building the manual
pages docbook2x is used.


RELEASE VERSIONING
==================

A new versioning scheme was chosen over the nss_ldap release scheme. The
scheme is a simple major.minor.micro numbering. Until a 1.0 release is made
the code will be considered work in progress. The interfaces may change and
features may be added and removed.


GENERAL DESIGN
==============

The basic design splits the functionality in three parts. The NSS part
interfaces with libc and translates the NSS requests into simple generic
requests (e.g. "get user with name test", "get group with gid 101" or "get all
shadow entries").

Another part is the PAM module which handles authentication requests from the
system.

Both these parts translate the queries in a higher-level simple protocol used
to communicate with the nslcd daemon. This daemon translates the requests into
LDAP searches. As a result the NSS and PAM modules don't need to known
anything about LDAP (in fact replacing it with another lookup method should be
very simple) and don't have to link with the LDAP libraries.

  libc NSS -> libnss_ldap.so
                 \
                  |->  nslcd  -> OpenLDAP -> LDAP server
                 /
  PAM stack -> pam_ldap.so

design goals
------------
* make it as simple as possible
* simpler configuration and semantics
* simpler, clearer and completer documentation
* split source code into manageable parts
* get rid of unneeded code and complexity
* have a stable, easily maintainable piece of quality software


NSS MODULE
==========

The NSS module is implemented in the nss directory. The functions are split
into files according to the database they support. Functions look like:

_nss_ldap_FUNCTION_r(...)
  This function opens the connection to the nslcd (with a time-out) builds the
  correct data structures and does a request (write()) to the nslcd waiting
  for an answer (again with a time-out)

The complete list of exported functions can be found in exports.linux and
prototypes.h. The NSS interface seems to be fairly libc-specific and is
currently tuned towards GNU Libc, although FreeBSD has a port based on this
code.

Currently a number of macros are used to build most of the function bodies for
these functions. Part of this is defined in the common/nslcd-prot.h file and
the NSS-specific stuff is in nss/common.h.

Some useful links:
http://mirrors.usc.edu/pub/gnu/Manuals/glibc-2.2.3/html_chapter/libc_28.html#SEC596
http://www.gnu.org/software/libc/manual/html_node/index.html


PAM MODULE
==========

The PAM module is implemented in the pam directory. Implementation is fairly
straight-forward. The PAM module stores some state between PAM calls in a
struct. The calls to nslcd are however stateless. The PAM module may however
supply some information that help lookups (most notably DNs of user entries).

Care must be taken with the communication because the nslcd requests are not
authenticated (e.g. changing passwords requests should include all
credentials). This is where the PAM module is different from the NSS module.
The PAM module could result in state changes on the LDAP server.

Some useful links:
http://www.kernel.org/pub/linux/libs/pam/
http://www.opengroup.org/tech/rfc/rfc86.0.html


THE COMMUNICATIONS PROTOCOL
===========================

The protocol used for communicating between the NSS library and PAM module on
one end and the nslcd daemon on the other is very simple and almost fully
described in the nslcd.h header file. The common/nslcd-prot.h header file
defines some macros that are used for reading and writing protocol entities
(strings, 32-bit integers, etc).

Every NSS database has a corresponding source file in the nss and the nslcd
directory. The PAM module is built up of a single file in both the pam and
nslcd directories.

If the protocol is changed in an incompatible way the protocol version should
be incremented in nslcd.h. There is currently no versioning scheme available
for this.

A special module (common/tio.c) was made so we can define simpler semantics
for time-out values and buffer sizes. All components use this module which
means that it includes functionality that is needed for both (e.g. large write
buffers for the server part and large resettable read buffers for the NSS
part). Maybe building two modules from the same source with different features
in them is an option (e.g. the NSS part needs the read buffers and handling of
SIGPIPE and the nslcd part needs the write buffers and possibly flushing in
the background).

The common directory also contains some other generally useful modules that
are used in some components.


SERVER PART
===========

At the server end a dispatcher picks up the request and delegates it to one of
the database specific functions.

nslcd_FUNCION(...)
  This functions fills in the correct parameters from the request. This
  function should write responses to the stream.


SECURITY NOTES
==============

This design does open up the system to more potential security issues as there
is now a local interface to a daemon with privileges. Before processes could
only potentially exploit bugs in the library and gain the privileges of the
process that was doing the name lookups. In this case the privileges of the
daemon are potentially exposed.

Extra care should be taken with processes that normally require extra
privileges (getting shadow entries, authentication, updating session
information, etc).

Any user on the system can perform nslcd queries so either the nslcd daemon
needs to check the userid of the caller or the request needs to contain the
needed credentials itself.


TEST SETUP
==========

In the test directory there are a number of tests available. See the file
README in the test directory for more details.