May 8, 2008 NSDISPATCH 3

### NAME

nsdispatch - name-service switch dispatcher routine

### LIBRARY

Standard C Library (libc, -lc)

### SYNOPSIS

```int` nsdispatch(`` ```void *nsdrv` ```const ns_dtab dtab[]` ```const char *database` ```const char *name` ```const ns_src defaults[]` ```...` )

### DESCRIPTION

The nsdispatch(``) function invokes the callback functions specified in ```dtab` in the order given in ```/etc/nsswitch.conf` for the database ```database` until the action criteria for a source of that database is fulfilled.

```nsdrv` is passed to each callback function to use as necessary (to pass back to the caller of nsdispatch(``)).

```dtab` is an array of ```ns_dtab` structures, which have the following format:

      typedef struct {
              const char *src;
              nss_method cb;
              void *cb_data;
      } ns_dtab;

      The
      dtab
      array should consist of one entry for each source type that has a
      static implementation,
      with
      src
      as the name of the source,
      cb
      as a callback function which handles that source, and
      cb_data
      as a pointer to arbitrary data to be passed to the callback function.
      The last entry in
      dtab
      should contain
      NULL
      values for
      src,
      cb,
      and
      cb_data.

      The callback function signature is described by the typedef:

      typedef int
      *nss_method(
      void *cbrv
      void *cbdata
      va_list ap
      );

      cbrv
      The
      nsdrv
      that
      nsdispatch()
      was invoked with.
      cbdata
      The
      cb_data
      member of the array entry for the source that this
      callback function implements in the
      dtab
      argument of
      nsdispatch().
      ap
      The
      ...
      arguments to
      nsdispatch(),
      converted to a

      va_list.

```database` and ```name` are used to select methods from optional per-source dynamically-loaded modules. ```name` is usually the name of the function calling nsdispatch(``). Note that the callback functions provided by ```dtab` take priority over those implemented in dynamically-loaded modules in the event of a conflict.

```defaults` contains a list of default sources to try in the case of a missing or corrupt nsswitch.conf(5), or if there isn't a relevant entry for ```database`. It is an array of ```ns_src` structures, which have the following format:

      typedef struct {
              const char *src;
              uint32_t flags;
      } ns_src;

      The
      defaults
      array should consist of one entry for each source to consult by default
      indicated by
      src,
      and
      flags
      set to the desired behavior
      (usually
      NS_SUCCESS;
      refer to
      Callback function return values
      for more information).
      The last entry in
      defaults
      should have
      src
      set to
      NULL
      and
      flags
      set to 0.

      Some invokers of
      nsdispatch()
      (such as
      setgrent(3))
      need to force all callback functions to be invoked,
      irrespective of the action criteria listed in
      nsswitch.conf(5).
      This can be achieved by adding
      NS_FORCEALL
      to
      defaults[0].flags
      before invoking
      nsdispatch().
      The return value of
      nsdispatch()
      will be the result of the final callback function invoked.

      For convenience, a global variable defined as:

      extern const ns_src __nsdefaultsrc[];

      exists which contains a single default entry for
      `files'
      for use by callers which don't require complicated default rules.

  ```...` are optional extra arguments, which are passed to the appropriate callback function as a stdarg(3) variable argument list of the type ```va_list`.

  nsdispatch returns the value of the callback function that caused the dispatcher to finish, or ```NS_NOTFOUND` otherwise.

  #### Dynamically-loaded module interface

  The nsdispatch(``) function loads callback functions from the run-time link-editor's search path using the following naming convention:

        nss_<source>.so.<version>

        <source>
        The source that the module implements.
        <version>
        The
        nsdispatch
        module interface version, which is defined by the integer
        NSS_MODULE_INTERFACE_VERSION,
        which has the value 0.

    When a module is loaded, nsdispatch(``) looks for and calls the following function in the module:

          ns_mtab *
          nss_module_register(
          const char *source
          u_int *nelems
          nss_module_unregister_fn *unreg
          );

          source
          The name of the source that the module implements, as used by
          nsdispatch()
          to construct the module's name.
          nelems
          A pointer to an unsigned integer that
          nss_module_register()
          should set to the number of elements in the

          ns_mtab
          array returned by
          nss_module_register(),
          or
          0
          if there was a failure.
          unreg
          A pointer to a function pointer that
          nss_module_register()
          can optionally set to an unregister function to be invoked when the module is
          unloaded, or
          NULL
          if there isn't one.

    The unregister function signature is described by the typedef:

          typedef void
          *nss_module_unregister_fn(
          ns_mtab *mtab
          u_int nelems
          );

          mtab
          The array of

          ns_mtab
          structures returned by
          nss_module_register().
          nelems
          The
          *nelems
          value set by
          nss_module_register().

    nss_module_register(``) returns an array of
    ```ns_mtab` structures (with ```*nelems` entries), or ```NULL` if there was a failure. The
    ```ns_mtab` structures have the following format:

          typedef struct {
                  const char *database;
                  const char *name;
                  nss_method method;
                  void *mdata;
          } ns_mtab;

          The
          mtab
          array should consist of one entry for each callback function (method)
          that is implemented,
          with
          database
          as the name of the database,
          name
          as the name of the callback function,
          method
          as the

          nss_method
          callback function that implements the method, and
          mdata
          as a pointer to arbitrary data to be passed to the callback function as its
          cbdata
          argument.

      #### Valid source types

      While there is support for arbitrary sources, the following #defines for commonly implemented sources are provided:

      #define Value
      NSSRC_FILES "files"
      NSSRC_DNS "dns"
      NSSRC_NIS "nis"
      NSSRC_COMPAT "compat"

      Refer to nsswitch.conf(5) for a complete description of what each source type is.

      #### Valid database types

      While there is support for arbitrary databases, the following #defines for currently implemented system databases are provided:

      #define Value
      NSDB_HOSTS "hosts"
      NSDB_GROUP "group"
      NSDB_GROUP_COMPAT "group_compat"
      NSDB_NETGROUP "netgroup"
      NSDB_NETWORKS "networks"
      NSDB_PASSWD "passwd"
      NSDB_PASSWD_COMPAT "passwd_compat"
      NSDB_SHELLS "shells"

      Refer to nsswitch.conf(5) for a complete description of what each database is.

      #### Callback function return values

      The callback functions should return one of the following values depending upon status of the lookup:

      Return value Status code
      NS_SUCCESS The requested entry was found.
      NS_NOTFOUND The entry is not present at this source.
      NS_TRYAGAIN The source is busy, and may respond to retries.
      NS_UNAVAIL The source is not responding, or entry is corrupt.

      ### CALLBACK FUNCTION API FOR STANDARD DATABASES

      The organization of the ```ap` argument for an nss_method(``) callback function for a standard method in a standard database is:
      1. Pointer to return value of the standard function.
      2. First argument of the standard function.
      3. (etc.)

      For example, given the standard function getgrnam(3):

            struct group *
            getgrnam(const char *name)

      the ```ap` organization used by the callback functions is:
      1. ```struct group **`
      2. ```const char *`

      NOTE: Not all standard databases are using this calling convention yet; those that aren't are noted below. These will be changed in the future.

      The callback function names and
      ```va_list` organization for various standard database callback functions are:

      #### Methods for hosts database

      NOTE: The method APIs for this database will be changing in the near future.

      getaddrinfo
        ```char *name`,
        ```const struct addrinfo *pai`

        Returns
        ```struct addrinfo *` via
        ```void *cbrv`.

      gethostbyaddr
        ```unsigned char *addr`,
        ```int addrlen`,
        ```int af`

        Returns
        ```struct hostent *` via
        ```void *cbrv`.

      gethostbyname
        ```char *name`,
        ```int namelen`,
        ```int af`

        Returns
        ```struct hostent *` via
        ```void *cbrv`.

      #### Methods for group and group_compat databases

      endgrent
        Empty ```ap`.

        All methods for all sources are invoked for this method name.

      getgrent
        ```struct group **retval`

        ```*retval` should be set to a pointer to an internal static
        ```struct group` on success, ```NULL` `otherwise.`

        getgrent(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getgrent_r
        ```int *retval`,
        ```struct group *grp`,
        ```char *buffer`,
        ```size_t buflen`,
        ```struct group **result`

        ```*retval` should be set to an appropriate errno(2) on failure.

        getgrent_r(3) returns 0 if nsdispatch(``) returns ```NS_SUCCESS` or ```NS_NOTFOUND`, and ```*retval` otherwise.

      getgrgid
        ```struct group **retval`,
        ```gid_t gid`

        ```*retval` should be set to a pointer to an internal static
        ```struct group` on success, ```NULL` `otherwise.`

        getgrgid(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getgrgid_r
        ```int *retval`,
        ```gid_t gid`,
        ```struct group *grp`,
        ```char *buffer`,
        ```size_t buflen`,
        ```struct group **result`

        ```*retval` should be set to an appropriate errno(2) on failure.

        getgrgid_r(3) returns 0 if nsdispatch(``) returns ```NS_SUCCESS` or ```NS_NOTFOUND`, and ```*retval` otherwise.

      getgrnam
        ```struct group **retval`,
        ```const char *name`

        ```*retval` should be set to a pointer to an internal static
        ```struct group` on success, ```NULL` `otherwise.`

        getgrnam(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getgrnam_r
        ```int *retval`,
        ```const char *name`,
        ```struct group *grp`,
        ```char *buffer`,
        ```size_t buflen`,
        ```struct group **result`

        ```*retval` should be set to an appropriate errno(2) on failure.

        getgrnam_r(3) returns 0 if nsdispatch(``) returns ```NS_SUCCESS` or ```NS_NOTFOUND`, and ```*retval` otherwise.

      getgroupmembership
        ```int *retval`,
        ```const char *name`,
        ```gid_t basegid`,
        ```gid_t *groups`,
        ```int maxgrp`,
        ```int *groupc`

        ```retval` is unused.

        Lookups for group_compat are also stopped if ```NS_SUCCESS` was returned to prevent multiple ``+:'' compat entries from being expanded.

        getgroupmembership(3) returns is -1 if ```*groupc` is greater than to ```maxgrp`, and 0 otherwise.

      setgroupent
        ```int *retval`,
        ```int stayopen`

        ```retval` should be set to 0 on failure and 1 on success.

        All methods for all sources are invoked for this method name.

      setgrent
        Empty ```ap`.

        All methods for all sources are invoked for this method name.

      #### Methods for netgroup database

      NOTE: The method APIs for this database will be changing in the near future.

      endnetgrent
        Empty ```ap`.

      lookup
        ```char *name`,
        ```char **line`,
        ```int bywhat`

        Find the given ```name` and return its value in ```line`. ```bywhat` is one of ```_NG_KEYBYNAME`, ```_NG_KEYBYUSER`, or ```_NG_KEYBYHOST`.

      getnetgrent
        ```int *retval`,
        ```const char **host`,
        ```const char **user`,
        ```const char **domain`

        ```*retval` should be set to 0 for no more netgroup members and 1 otherwise.

        getnetgrent(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, 0 otherwise.

      innetgr
        ```int *retval`,
        ```const char *grp`,
        ```const char *host`,
        ```const char *user`,
        ```const char *domain`

        ```*retval` should be set to 1 for a successful match and 0 otherwise.

      setnetgrent
        ```const char *netgroup`

      #### Methods for networks database

      getnetbyaddr
        ```struct netent **retval`,
        ```uint32_t net`,
        ```int type`

        ```*retval` should be set to a pointer to an internal static
        ```struct netent` on success, ```NULL` `otherwise.`

        getnetbyaddr(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getnetbyname
        ```struct netent **retval`,
        ```const char *name`

        ```*retval` should be set to a pointer to an internal static
        ```struct netent` on success, ```NULL` `otherwise.`

        getnetbyname(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      #### Methods for passwd and passwd_compat databases

      endpwent
        Empty ```ap`.

        All methods for all sources are invoked for this method name.

      getpwent
        ```struct passwd **retval`

        ```*retval` should be set to a pointer to an internal static
        ```struct passwd` on success, ```NULL` `otherwise.`

        getpwent(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getpwent_r
        ```int *retval`,
        ```struct passwd *pw`,
        ```char *buffer`,
        ```size_t buflen`,
        ```struct passwd **result`

        ```*retval` should be set to an appropriate errno(2) on failure.

        getpwent_r(3) returns 0 if nsdispatch(``) returns ```NS_SUCCESS` or ```NS_NOTFOUND`, and ```*retval` otherwise.

      getpwnam
        ```struct passwd **retval`,
        ```const char *name`

        ```*retval` should be set to a pointer to an internal static
        ```struct passwd` on success, ```NULL` `otherwise.`

        getpwnam(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getpwnam_r
        ```int *retval`,
        ```const char *name`,
        ```struct passwd *pw`,
        ```char *buffer`,
        ```size_t buflen`,
        ```struct passwd **result`

        ```*retval` should be set to an appropriate errno(2) on failure.

        getpwnam_r(3) returns 0 if nsdispatch(``) returns ```NS_SUCCESS` or ```NS_NOTFOUND`, and ```*retval` otherwise.

      getpwuid
        ```struct passwd **retval`,
        ```uid_t uid`

        ```*retval` should be set to a pointer to an internal static
        ```struct passwd` on success, ```NULL` `otherwise.`

        getpwuid(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, ```NULL` otherwise.

      getpwuid_r
        ```int *retval`,
        ```uid_t uid`,
        ```struct passwd *pw`,
        ```char *buffer`,
        ```size_t buflen`,
        ```struct passwd **result`

        ```*retval` should be set to an appropriate errno(2) on failure.

        `getpwuid_r` returns 0 if nsdispatch(``) returns ```NS_SUCCESS` or ```NS_NOTFOUND`, and ```*retval` otherwise.

      setpassent
        ```int *retval`,
        ```int stayopen`

        ```retval` should be set to 0 on failure and 1 on success.

        All methods for all sources are invoked for this method name.

      setpwent
        Empty ```ap`.

        All methods for all sources are invoked for this method name.

      #### Methods for shells database

      endusershell
        Empty ```ap`.

        All methods for all sources are invoked for this method name.

      getusershell
        ```char **retval`

        getusershell(3) returns ```*retval` if nsdispatch(``) returns ```NS_SUCCESS`, and 0 otherwise.

      setusershell
        Empty ```ap`.

        All methods for all sources are invoked for this method name.

      ### SEE ALSO

      ld.elf_so(1), hesiod(3), stdarg(3), ypclnt(3), nsswitch.conf(5)

      ### HISTORY

      The nsdispatch routines first appeared in NetBSD1.4. Support for dynamically-loaded modules first appeared in NetBSD3.0.

      ### AUTHORS

      Luke Mewburn <lukem@NetBSD.org> wrote this freely distributable name-service switch implementation, using ideas from the ULTRIX svc.conf(5) and Solaris nsswitch.conf(4) manual pages. Support for dynamically-loaded modules was added by Jason Thorpe <thorpej@NetBSD.org>, based on code developed by the FreeBSD Project.