about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2018-08-02 22:17:55 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2018-08-02 22:17:55 +0000
commit68594d15c56a21e3d4d8cd12fefbc5bbf0af002f (patch)
tree7a1d7d9ed96d52fb1da563a5c74b07fcee8fda99
parent0ac545543b541824c2a04e5643ee6024e162a4cd (diff)
downloadnsss-68594d15c56a21e3d4d8cd12fefbc5bbf0af002f.tar.gz
nsss-68594d15c56a21e3d4d8cd12fefbc5bbf0af002f.tar.xz
nsss-68594d15c56a21e3d4d8cd12fefbc5bbf0af002f.zip
Complete libnsssd and libnsss documentation
-rw-r--r--doc/libnsss/nsss-switch.html188
-rw-r--r--doc/libnsss/nsss-unix.html203
-rw-r--r--doc/libnsssd/index.html45
3 files changed, 433 insertions, 3 deletions
diff --git a/doc/libnsss/nsss-switch.html b/doc/libnsss/nsss-switch.html
index 224cea6..006b457 100644
--- a/doc/libnsss/nsss-switch.html
+++ b/doc/libnsss/nsss-switch.html
@@ -21,9 +21,195 @@
 
 <h2> General information </h2>
 
+<p>
+ The <a href="//git.skarnet.org/cgi-bin/cgit.cgi/nsss/tree/src/include/nsss/nsss-switch.h">nsss/nsss-switch.h</a>
+functions in libnsss provide a clean interface to get user/group data from a
+<em>nsss daemon</em>, for instance one implemented via
+<a href="../nsssd-unix.html">nsssd-unix</a> or
+<a href="../nsssd-nslcd.html">nsssd-nslcd</a>. They are the C client library
+to such a daemon.
+</p>
+
+<p>
+ Most of the following functions take, in addition to their obvious arguments,
+a <em>tain_t const *</em> argument conventionally named <em>deadline</em> and
+a <em>tain_t *</em> argument conventionally named <em>stamp</em>. These two
+arguments are there to ensure that the function, which connects to another
+process in an otherwise synchronous manner, does not block forever. How to
+use these arguments is explained, for instance,
+<a href="//skarnet.org/s6/libs6/ftrigr.html#synctimed">here</a>.
+A function <em>foobar</em> also has a version named <em>foobar_g</em> that
+only takes the <em>deadline</em> argument, assuming the current timestamp
+is held in the STAMP global variable.
+</p>
+
+<p>
+ All the functions take as their first argument a pointer to a handle
+that has the <tt>nsss_switch_t</tt> type. This handle must be declared and
+initialized to NSSS_SWITCH_ZERO prior to any call. It can be declared in the stack.
+</p>
+
 <h2> Programming </h2>
 
-<p> TODO: to be completed. </p>
+<h4><code>int nsss_switch_start (nsss_switch_t *a, unsigned int what, char const *path, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Opens a session with a nsss daemon listening to a Unix domain socket
+located at <em>path</em>. <em>*a</em> must be
+NSSS_SWITCH_ZERO prior to the call. The nature of the session depends on
+the <em>what</em> argument, which should be one of NSSS_SWITCH_PWD,
+NSSS_SWITCH_GRP or NSSS_SWITCH_SHADOW depending on whether subsequent
+requests will query the user, group or shadow database.
+ On error, the function returns 0, and sets errno.
+On success, it returns 1, and <em>*a</em> is a handle to a session with
+the nsssd daemon. This function must be called for every batch of
+communication with a nsssd service, not only for enumerations.
+</p>
+
+<h4><code>void nsss_switch_end (nsss_switch_t *a, unsigned int what)</code></h4>
+<p>
+ Closes the current session. The <em>what</em> argument must be the same one
+that has been given to <tt>nsss_switch_start</tt>. After this function returns,
+<em>*a</em> can be reused.
+</p>
+
+<h4><code>int nsss_switch_pwd_rewind (nsss_switch_t *a, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>setpwent()</tt> operation on the current session.
+Returns 1 on success, and 0 (and sets errno) on error.
+</p>
+
+<h4><code>int nsss_switch_pwd_end (nsss_switch_t *a, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>endpwent()</tt> operation on the current session,
+i.e. ends an enumeration. Returns 1 on success, and 0 (and sets errno)
+on error.
+</p>
+
+<h4><code>int nsss_switch_pwd_getbyname (nsss_switch_t *a, struct passwd *pw, stralloc *sa, char const *name, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>getpwnam(<em>name</em>)</tt> on the current session.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*pw</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. If <em>name</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_switch_pwd_getbyuid (nsss_switch_t *a, struct passwd *pw, stralloc *sa, uid_t uid, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>getpwuid(<em>uid</em>)</tt> on the current session.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*pw</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. If <em>uid</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_switch_pwd_get (nsss_switch_t *a, struct passwd *pw, stralloc *sa, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a a <tt>getpwent()</tt> on the current session,
+i.e. get the next entry as part of an enumeration.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*pw</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. On EOF, the function returns 0 without changing errno.
+</p>
+
+<h4><code>int nsss_switch_grp_rewind (nsss_switch_t *a, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>setgrent()</tt> operation on the current session.
+Returns 1 on success, and 0 (and sets errno) on error.
+</p>
+
+<h4><code>void nsss_switch_grp_end (nsss_switch_t *a, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>endgrent()</tt> operation on the current session,
+i.e. ends an enumeration. Returns 1 on success, and 0 (and sets errno)
+on error.
+</p>
+
+<h4><code>int nsss_switch_grp_getbyname (nsss_switch_t *a, struct group *gr, stralloc *sa, genalloc *ga, char const *name, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a a <tt>getgrnam(<em>name</em>)</tt> on the current session.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*gr</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings, and the <em>*ga</em>
+<a href="//skarnet.org/skalibs/libstddjb/genalloc.html">genalloc</a>,
+which must be able to hold objects of type <tt>char *</tt>,
+to store pointers for the <tt>gr->gr_mem</tt> field.
+ If <em>name</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_switch_grp_getbygid (nsss_switch_t *a, struct group *gr, stralloc *sa, genalloc *ga, gid_t gid, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>getgrgid(<em>gid</em>)</tt> on the current session.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*gr</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings, and the <em>*ga</em>
+<a href="//skarnet.org/skalibs/libstddjb/genalloc.html">genalloc</a>,
+which must be able to hold objects of type <tt>char *</tt>,
+to store pointers for the <tt>gr->gr_mem</tt> field.
+ If <em>gid</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_switch_grp_get (nsss_switch_t *a, struct group *gr, stralloc *sa, genalloc *ga, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>getgrent()</tt> on the current session,
+i.e. get the next entry as part of an enumeration.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*gr</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings, and the <em>*ga</em>
+<a href="//skarnet.org/skalibs/libstddjb/genalloc.html">genalloc</a>,
+which must be able to hold objects of type <tt>char *</tt>,
+to store pointers for the <tt>gr->gr_mem</tt> field.
+ On EOF, the function returns 0 without changing errno.
+</p>
+
+<h4><code>int nsss_switch_shadow_rewind (nsss_switch_t *a, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>setspent()</tt> operation on the current session.
+Returns 1 on success, and 0 (and sets errno) on error.
+</p>
+
+<h4><code>int nsss_switch_shadow_end (nsss_switch_t *a, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>endspent()</tt> operation on the current session,
+i.e. ends an enumeration. Returns 1 on success, and 0 (and sets errno)
+on error.
+</p>
+
+<h4><code>int nsss_switch_shadow_getbyname (nsss_switch_t *a, struct spwd *sp, stralloc *sa, char const *name, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>getspnam(<em>name</em>)</tt> on the current session.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*sp</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. If <em>name</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_switch_shadow_get (nsss_switch_t *a, struct spwd *sp, stralloc *sa, tain_t const *deadline, tain_t *stamp)</code></h4>
+<p>
+Performs the equivalent of a <tt>getspent()</tt> on the current session,
+i.e. get the next entry as part of an enumeration.
+On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*sp</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. On EOF, the function returns 0 without changing errno.
+</p>
 
 </body>
 </html>
diff --git a/doc/libnsss/nsss-unix.html b/doc/libnsss/nsss-unix.html
index b51985b..931e532 100644
--- a/doc/libnsss/nsss-unix.html
+++ b/doc/libnsss/nsss-unix.html
@@ -21,9 +21,210 @@
 
 <h2> General information </h2>
 
+<p>
+ The <a href="//git.skarnet.org/cgi-bin/cgit.cgi/nsss/tree/src/include/nsss/nsss-unix.h">nsss/nsss-unix.h</a>
+functions in libnsss provide a clean interface to get user/group data from the regular
+<tt>/etc/passwd</tt>, <tt>/etc/group</tt> and <tt>/etc/shadow</tt> text files.
+</p>
+
+<p>
+ All the following functions take as their first argument a pointer to a handle
+that has the <tt>nsss_unix_t</tt> type. This handle must be declared and
+initialized to NSSS_UNIX_ZERO prior to any call. It can be declared in the stack.
+</p>
+
 <h2> Programming </h2>
 
-<p> TODO: to be completed. </p>
+<h4><code>int nsss_unix_pwd_start (nsss_unix_t *a)</code></h4>
+<p>
+Opens a session with <tt>/etc/passwd</tt>. <em>*a</em> must be
+NSSS_UNIX_ZERO prior to the call. On error, returns 0, and sets errno.
+On success, returns 1, and <em>*a</em> is a handle to an <tt>/etc/passwd</tt>
+session. This function must be called <em>even for a non-enumeration lookup</em>.
+</p>
+
+<h4><code>int nsss_unix_pwd_maybe_start (nsss_unix_t *a)</code></h4>
+<p>
+Opens a session with <tt>/etc/passwd</tt> if it hasn't been opened yet.
+On error, returns 0, and sets errno.
+On success, returns 1, and <em>*a</em> is a handle to an <tt>/etc/passwd</tt>
+session. Calling this function when <em>*a</em> is already opened to an
+<tt>/etc/passwd</tt> session simply returns 1.
+</p>
+
+<h4><code>int nsss_unix_pwd_rewind (nsss_unix_t *a)</code></h4>
+<p>
+Performs a <tt>setpwent()</tt> operation on the current session.
+Returns 1 on success, and 0 (and sets errno) on error.
+</p>
+
+<h4><code>void nsss_unix_pwd_end (nsss_unix_t *a)</code></h4>
+<p>
+Closes the current <tt>/etc/passwd</tt> session. After this
+function returns, <em>*a</em> can be reused with another
+<tt>nsss_unix_*_start()</tt> function.
+</p>
+
+<h4><code>int nsss_unix_pwd_getbyname (nsss_unix_t *a, struct passwd *pw, stralloc *sa, char const *name)</code></h4>
+<p>
+Performs a <tt>getpwnam(<em>name</em>)</tt> on the current, open,
+<tt>/etc/passwd</tt> session. On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*pw</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. If <em>name</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_unix_pwd_getbyuid (nsss_unix_t *a, struct passwd *pw, stralloc *sa, uid_t uid)</code></h4>
+<p>
+Performs a <tt>getpwuid(<em>uid</em>)</tt> on the current, open,
+<tt>/etc/passwd</tt> session. On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*pw</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. If <em>uid</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_unix_pwd_get (nsss_unix_t *a, struct passwd *pw, stralloc *sa)</code></h4>
+<p>
+Performs a <tt>getpwent()</tt> on the current, open,
+<tt>/etc/passwd</tt> session (i.e. get the next entry in the file, as
+part of an enumeration). On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*pw</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. On EOF, the function returns 0 without changing errno.
+</p>
+
+
+<h4><code>int nsss_unix_grp_start (nsss_unix_t *a)</code></h4>
+<p>
+Opens a session with <tt>/etc/group</tt>. <em>*a</em> must be
+NSSS_UNIX_ZERO prior to the call. On error, returns 0, and sets errno.
+On success, returns 1, and <em>*a</em> is a handle to an <tt>/etc/group</tt>
+session. This function must be called <em>even for a non-enumeration lookup</em>.
+</p>
+
+<h4><code>int nsss_unix_grp_maybe_start (nsss_unix_t *a)</code></h4>
+<p>
+Opens a session with <tt>/etc/group</tt> if it hasn't been opened yet.
+On error, returns 0, and sets errno.
+On success, returns 1, and <em>*a</em> is a handle to an <tt>/etc/group</tt>
+session. Calling this function when <em>*a</em> is already opened to an
+<tt>/etc/group</tt> session simply returns 1.
+</p>
+
+<h4><code>int nsss_unix_grp_rewind (nsss_unix_t *a)</code></h4>
+<p>
+Performs a <tt>setgrent()</tt> operation on the current session.
+Returns 1 on success, and 0 (and sets errno) on error.
+</p>
+
+<h4><code>void nsss_unix_grp_end (nsss_unix_t *a)</code></h4>
+<p>
+Closes the current <tt>/etc/group</tt> session. After this
+function returns, <em>*a</em> can be reused with another
+<tt>nsss_unix_*_start()</tt> function.
+</p>
+
+<h4><code>int nsss_unix_grp_getbyname (nsss_unix_t *a, struct group *gr, stralloc *sa, genalloc *ga, char const *name)</code></h4>
+<p>
+Performs a <tt>getgrnam(<em>name</em>)</tt> on the current, open,
+<tt>/etc/group</tt> session. On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*gr</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings, and the <em>*ga</em>
+<a href="//skarnet.org/skalibs/libstddjb/genalloc.html">genalloc</a>,
+which must be able to hold objects of type <tt>char *</tt>,
+to store pointers for the <tt>gr->gr_mem</tt> field.
+ If <em>name</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_unix_grp_getbygid (nsss_unix_t *a, struct group *gr, stralloc *sa, genalloc *ga, gid_t gid)</code></h4>
+<p>
+Performs a <tt>getgrgid(<em>gid</em>)</tt> on the current, open,
+<tt>/etc/group</tt> session. On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*gr</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings, and the <em>*ga</em>
+<a href="//skarnet.org/skalibs/libstddjb/genalloc.html">genalloc</a>,
+which must be able to hold objects of type <tt>char *</tt>,
+to store pointers for the <tt>gr->gr_mem</tt> field.
+ If <em>gid</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_unix_grp_get (nsss_unix_t *a, struct group *gr, stralloc *sa, genalloc *ga)</code></h4>
+<p>
+Performs a <tt>getgrent()</tt> on the current, open,
+<tt>/etc/group</tt> session (i.e. get the next entry in the file, as
+part of an enumeration). On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*gr</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings, and the <em>*ga</em>
+<a href="//skarnet.org/skalibs/libstddjb/genalloc.html">genalloc</a>,
+which must be able to hold objects of type <tt>char *</tt>,
+to store pointers for the <tt>gr->gr_mem</tt> field.
+ On EOF, the function returns 0 without changing errno.
+</p>
+
+<h4><code>int nsss_unix_shadow_start (nsss_unix_t *a)</code></h4>
+<p>
+Opens a session with <tt>/etc/shadow</tt>. <em>*a</em> must be
+NSSS_UNIX_ZERO prior to the call. On error, returns 0, and sets errno.
+On success, returns 1, and <em>*a</em> is a handle to an <tt>/etc/shadow</tt>
+session. This function must be called <em>even for a non-enumeration lookup</em>.
+</p>
+
+<h4><code>int nsss_unix_shadow_maybe_start (nsss_unix_t *a)</code></h4>
+<p>
+Opens a session with <tt>/etc/shadow</tt> if it hasn't been opened yet.
+On error, returns 0, and sets errno.
+On success, returns 1, and <em>*a</em> is a handle to an <tt>/etc/shadow</tt>
+session. Calling this function when <em>*a</em> is already opened to an
+<tt>/etc/shadow</tt> session simply returns 1.
+</p>
+
+<h4><code>int nsss_unix_shadow_rewind (nsss_unix_t *a)</code></h4>
+<p>
+Performs a <tt>setspent()</tt> operation on the current session.
+Returns 1 on success, and 0 (and sets errno) on error.
+</p>
+
+<h4><code>void nsss_unix_shadow_end (nsss_unix_t *a)</code></h4>
+<p>
+Closes the current <tt>/etc/shadow</tt> session. After this
+function returns, <em>*a</em> can be reused with another
+<tt>nsss_unix_*_start()</tt> function.
+</p>
+
+<h4><code>int nsss_unix_shadow_getbyname (nsss_unix_t *a, struct spwd *sp, stralloc *sa, char const *name)</code></h4>
+<p>
+Performs a <tt>getspnam(<em>name</em>)</tt> on the current, open,
+<tt>/etc/shadow</tt> session. On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*sp</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. If <em>name</em> is not found, the function returns 0
+without changing errno.
+</p>
+
+<h4><code>int nsss_unix_shadow_get (nsss_unix_t *a, struct spwd *sp, stralloc *sa)</code></h4>
+<p>
+Performs a <tt>getspent()</tt> on the current, open,
+<tt>/etc/shadow</tt> session (i.e. get the next entry in the file, as
+part of an enumeration). On error, returns 0 and sets errno.
+On success, returns 1, and stores the result into <em>*sp</em>,
+using the <em>*sa</em>
+<a href="//skarnet.org/skalibs/libstddjb/stralloc.html">stralloc</a> to
+store strings. On EOF, the function returns 0 without changing errno.
+</p>
 
 </body>
 </html>
diff --git a/doc/libnsssd/index.html b/doc/libnsssd/index.html
index ec2c5d4..76eb7df 100644
--- a/doc/libnsssd/index.html
+++ b/doc/libnsssd/index.html
@@ -94,8 +94,51 @@ This function must deinitialize the handle and free all
 related resources: close connections to external processes, etc.
 </p>
 
+<h4><code>int nsssd_pwd_start (void *handle)</code></h4>
 <p>
- TODO: to be completed.
+This function will be called at the start of a passwd enumeration.
+It must return nonzero on success and 0 on error.
+</p>
+
+<h4><code>int nsssd_pwd_rewind (void *handle)</code></h4>
+<p>
+This function will be called on a <em>setpwent()</em> call.
+It must rewind the current enumeration to the start of the
+database.
+It must return nonzero on success and 0 on error.
+</p>
+
+<h4><code>int nsssd_pwd_get (void *handle, struct passwd *pw)</code></h4>
+<p>
+This function will be called on every <em>getpwent()</em> call, i.e.
+on every iteration of an enumeration. On error, it must return 0; on
+success, it must return nonzero and store the obtained passwd structure
+into <em>*pw</em>.
+</p>
+
+<h4><code>void nsssd_pwd_end (void *handle)</code></h4>
+<p>
+This function will be called at the end of a passwd enumeration.
+</p>
+
+<h4><code>int nsssd_pwd_getbyuid (void *handle, struct passwd *pw, uid_t uid)</code></h4>
+<p>
+This function must implement a <em>getpwuid(uid)</em> call. On error, it must
+return 0; on success, it must return nonzero and store the result into
+<em>*pw</em>.
+</p>
+
+<h4><code>int nsssd_pwd_getbyname (void *handle, struct passwd *pw, char const *name)</code></h4>
+<p>
+This function must implement a <em>getpwnam(name)</em> call. On error, it must
+return 0; on success, it must return nonzero and store the result into
+<em>*pw</em>.
+</p>
+
+<p>
+ Similar functions for the group and shadow databases must also be implemented.
+The full list can be found in the
+<a href="//git.skarnet.org/cgi-bin/cgit.cgi/nsss/tree/src/include/nsss/nsssd.h">nsss/nsssd.h</a> header.
 </p>
 
 </body>