Back to index

glibc  2.9
Defines | Functions
hesiod-grp.c File Reference
#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <hesiod.h>
#include <nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include "nss_hesiod.h"
#include <nss/nss_files/files-parse.c>

Go to the source code of this file.

Defines

#define ENTNAME   grent
#define STRUCTURE   group
#define EXTERN_PARSER

Functions

enum nss_status _nss_hesiod_setgrent (int stayopen)
enum nss_status _nss_hesiod_endgrent (void)
static enum nss_status lookup (const char *name, const char *type, struct group *grp, char *buffer, size_t buflen, int *errnop)
enum nss_status _nss_hesiod_getgrnam_r (const char *name, struct group *grp, char *buffer, size_t buflen, int *errnop)
enum nss_status _nss_hesiod_getgrgid_r (gid_t gid, struct group *grp, char *buffer, size_t buflen, int *errnop)
static int internal_gid_in_list (const gid_t *list, const gid_t g, long int len)
static enum nss_status internal_gid_from_group (void *context, const char *groupname, gid_t *group)
enum nss_status _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start, long int *size, gid_t **groupsp, long int limit, int *errnop)

Define Documentation

#define ENTNAME   grent

Definition at line 33 of file hesiod-grp.c.

#define EXTERN_PARSER

Definition at line 35 of file hesiod-grp.c.

#define STRUCTURE   group

Definition at line 34 of file hesiod-grp.c.


Function Documentation

Definition at line 45 of file hesiod-grp.c.

{
  return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_hesiod_getgrgid_r ( gid_t  gid,
struct group grp,
char *  buffer,
size_t  buflen,
int errnop 
)

Definition at line 107 of file hesiod-grp.c.

{
  char gidstr[21];   /* We will probably never have a gid_t with more
                        than 64 bits.  */

  snprintf (gidstr, sizeof gidstr, "%d", gid);

  return lookup (gidstr, "gid", grp, buffer, buflen, errnop);
}

Here is the call graph for this function:

enum nss_status _nss_hesiod_getgrnam_r ( const char *  name,
struct group grp,
char *  buffer,
size_t  buflen,
int errnop 
)

Definition at line 100 of file hesiod-grp.c.

{
  return lookup (name, "group", grp, buffer, buflen, errnop);
}

Here is the call graph for this function:

enum nss_status _nss_hesiod_initgroups_dyn ( const char *  user,
gid_t  group,
long int start,
long int size,
gid_t **  groupsp,
long int  limit,
int errnop 
)

Definition at line 174 of file hesiod-grp.c.

{
  enum nss_status status = NSS_STATUS_SUCCESS;
  char **list = NULL;
  char *p;
  void *context;
  gid_t *groups = *groupsp;
  int save_errno;

  context = _nss_hesiod_init ();
  if (context == NULL)
    return NSS_STATUS_UNAVAIL;

  list = hesiod_resolve (context, user, "grplist");

  if (list == NULL)
    {
      hesiod_end (context);
      return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
    }

  if (!internal_gid_in_list (groups, group, *start))
    {
      if (__builtin_expect (*start == *size, 0))
       {
         /* Need a bigger buffer.  */
         gid_t *newgroups;
         long int newsize;

         if (limit > 0 && *size == limit)
           /* We reached the maximum.  */
           goto done;

         if (limit <= 0)
           newsize = 2 * *size;
         else
           newsize = MIN (limit, 2 * *size);

         newgroups = realloc (groups, newsize * sizeof (*groups));
         if (newgroups == NULL)
           goto done;
         *groupsp = groups = newgroups;
         *size = newsize;
       }

      groups[(*start)++] = group;
    }

  save_errno = errno;

  p = *list;
  while (*p != '\0')
    {
      char *endp;
      char *q;
      long int val;

      status = NSS_STATUS_NOTFOUND;

      q = p;
      while (*q != '\0' && *q != ':' && *q != ',')
       ++q;

      if (*q != '\0')
       *q++ = '\0';

      __set_errno (0);
      val = strtol (p, &endp, 10);
      /* Test whether the number is representable in a variable of
         type `gid_t'.  If not ignore the number.  */
      if ((sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
         && errno == 0)
       {
         if (*endp == '\0' && endp != p)
           {
             group = val;
             status = NSS_STATUS_SUCCESS;
           }
         else
           status = internal_gid_from_group (context, p, &group);

         if (status == NSS_STATUS_SUCCESS
             && !internal_gid_in_list (groups, group, *start))
           {
             if (__builtin_expect (*start == *size, 0))
              {
                /* Need a bigger buffer.  */
                gid_t *newgroups;
                long int newsize;

                if (limit > 0 && *size == limit)
                  /* We reached the maximum.  */
                  goto done;

                if (limit <= 0)
                  newsize = 2 * *size;
                else
                  newsize = MIN (limit, 2 * *size);

                newgroups = realloc (groups, newsize * sizeof (*groups));
                if (newgroups == NULL)
                  goto done;
                *groupsp = groups = newgroups;
                *size = newsize;
              }

             groups[(*start)++] = group;
           }
       }

      p = q;
    }

  __set_errno (save_errno);

 done:
  hesiod_free_list (context, list);
  hesiod_end (context);

  return NSS_STATUS_SUCCESS;
}

Here is the call graph for this function:

enum nss_status _nss_hesiod_setgrent ( int  stayopen)

Definition at line 39 of file hesiod-grp.c.

{
  return NSS_STATUS_SUCCESS;
}
static enum nss_status internal_gid_from_group ( void *  context,
const char *  groupname,
gid_t group 
) [static]

Definition at line 132 of file hesiod-grp.c.

{
  char **grp_res;
  enum nss_status status = NSS_STATUS_NOTFOUND;

  grp_res = hesiod_resolve (context, groupname, "group");
  if (grp_res != NULL && *grp_res != NULL)
    {
      char *p = *grp_res;

      while (*p != '\0' && *p != ':')
       ++p;
      while (*p != '\0' && *p == ':')
       ++p;
      while (*p != '\0' && *p != ':')
       ++p;
      while (*p != '\0' && *p == ':')
       ++p;
      if (*p == ':')
       {
         char *endp;
         char *q = ++p;
         long int val;

         q = p;
         while (*q != '\0' && *q != ':')
           ++q;

         val = strtol (p, &endp, 10);
         if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val)
           {
             *group = val;
             if (endp == q && endp != p)
              status = NSS_STATUS_SUCCESS;
           }
        }
      hesiod_free_list (context, grp_res);
    }
  return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int internal_gid_in_list ( const gid_t list,
const gid_t  g,
long int  len 
) [static]

Definition at line 119 of file hesiod-grp.c.

{
  while (len > 0)
    {
      if (*list == g)
       return 1;
      --len;
      ++list;
    }
  return 0;
}

Here is the caller graph for this function:

static enum nss_status lookup ( const char *  name,
const char *  type,
struct group grp,
char *  buffer,
size_t  buflen,
int errnop 
) [static]

Definition at line 51 of file hesiod-grp.c.

{
  struct parser_data *data = (void *) buffer;
  size_t linebuflen;
  void *context;
  char **list;
  int parse_res;
  size_t len;
  int olderr = errno;

  context = _nss_hesiod_init ();
  if (context == NULL)
    return NSS_STATUS_UNAVAIL;

  list = hesiod_resolve (context, name, type);
  if (list == NULL)
    {
      int err = errno;
      hesiod_end (context);
      __set_errno (olderr);
      return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
    }

  linebuflen = buffer + buflen - data->linebuffer;
  len = strlen (*list) + 1;
  if (linebuflen < len)
    {
      hesiod_free_list (context, list);
      hesiod_end (context);
      *errnop = ERANGE;
      return NSS_STATUS_TRYAGAIN;
    }

  memcpy (data->linebuffer, *list, len);
  hesiod_free_list (context, list);
  hesiod_end (context);

  parse_res = _nss_files_parse_grent (buffer, grp, data, buflen, errnop);
  if (parse_res < 1)
    {
      __set_errno (olderr);
      return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
    }

  return NSS_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function: