Example #1
0
static enum nss_status internal_getgrent(struct group *gr, char *buffer,
					 size_t buflen, int *errnop,
					 void *cmpdata,
					 int (*cmpFunc)(void *, void *))
{
	struct group *grpp;
	int r = 0;
	enum nss_status result = NSS_STATUS_SUCCESS;

	if ( (fgrent.stream == NULL) || (cmpdata != NULL) )
		result = internal_setent(&fgrent);

	if (result != NSS_STATUS_SUCCESS)
		return result;

	while (!r) {
		r = fgetgrent_r(fgrent.stream, gr, buffer, buflen, &grpp);

		if ( (cmpFunc == NULL) ||
		     (cmpFunc(gr, cmpdata)))
			break;
	}


	if (r == ERANGE) {
		*errnop = ERANGE;
		return NSS_STATUS_TRYAGAIN;
	}

	if (r)
		return NSS_STATUS_NOTFOUND;

	return result;
}
Example #2
0
/* Maintenance of the shared handle open on the database.  */
enum nss_status
_nss_db_setnetgrent (const char *group, struct __netgrent *result)
{
  struct nss_db_map state;
  enum nss_status status = internal_setent (DBFILE, &state);

  if (status == NSS_STATUS_SUCCESS)
    {
      const struct nss_db_header *header = state.header;
      const stridx_t *hashtable
	= (const stridx_t *) ((const char *) header
			      + header->dbs[0].hashoffset);
      const char *valstrtab = (const char *) header + header->valstroffset;
      uint32_t hashval = __hash_string (group);
      size_t grouplen = strlen (group);
      size_t hidx = hashval % header->dbs[0].hashsize;
      size_t hval2 = 1 + hashval % (header->dbs[0].hashsize - 2);

      status = NSS_STATUS_NOTFOUND;
      while (hashtable[hidx] != ~((stridx_t) 0))
	{
	  const char *valstr = valstrtab + hashtable[hidx];

	  if (strncmp (valstr, group, grouplen) == 0
	      && isblank (valstr[grouplen]))
	    {
	      const char *cp = &valstr[grouplen + 1];
	      while (isblank (*cp))
		++cp;
	      if (*cp != '\0')
		{
		  result->data = strdup (cp);
		  if (result->data == NULL)
		    status = NSS_STATUS_TRYAGAIN;
		  else
		    {
		      status = NSS_STATUS_SUCCESS;
		      result->cursor = result->data;
		    }
		  break;
		}
	    }

	  if ((hidx += hval2) >= header->dbs[0].hashsize)
	    hidx -= header->dbs[0].hashsize;
	}

      internal_endent (&state);
    }

  return status;

}
/* Open the database.  */
enum nss_status
CONCAT(_nss_db_set,ENTNAME) (int stayopen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  status = internal_setent (DBFILE, &db);

  /* Remember STAYOPEN flag.  */
  if (db != NULL)
    keep_db |= stayopen;
  /* Reset the sequential index.  */
  entidx = 0;

  __libc_lock_unlock (lock);

  return status;
}
Example #4
0
/* Thread-safe, exported version of that.  */
enum nss_status
CONCAT(CONCAT(CONCAT(_nss_, ALTFILES_MODULE_NAME), _set), ENTNAME) (int stayopen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  status = internal_setent (stayopen);

  if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
    {
      fclose (stream);
      stream = NULL;
      status = NSS_STATUS_UNAVAIL;
    }

  last_use = getent;

  __libc_lock_unlock (lock);

  return status;
}
Example #5
0
enum nss_status
_nss_db_initgroups_dyn (const char *user, gid_t group, long int *start,
			long int *size, gid_t **groupsp, long int limit,
			int *errnop)
{
  struct nss_db_map state = { NULL, 0 };
  enum nss_status status = internal_setent (_PATH_VARDB "group.db", &state);
  if (status != NSS_STATUS_SUCCESS)
    {
      *errnop = errno;
      return status;
    }

  const struct nss_db_header *header = state.header;
  int i;
  for (i = 0; i < header->ndbs; ++i)
    if (header->dbs[i].id == ':')
      break;
  if (i == header->ndbs)
    {
      status = NSS_STATUS_UNAVAIL;
      goto out;
    }

  const stridx_t *hashtable
    = (const stridx_t *) ((const char *) header
			  + header->dbs[i].hashoffset);
  const char *valstrtab = (const char *) header + header->valstroffset;
  size_t userlen = strlen (user);
  uint32_t hashval = __hash_string (user);
  size_t hidx = hashval % header->dbs[i].hashsize;
  size_t hval2 = 1 + hashval % (header->dbs[i].hashsize - 2);

  gid_t *groups = *groupsp;

  status = NSS_STATUS_NOTFOUND;
  while (hashtable[hidx] != ~((stridx_t) 0))
    {
      const char *valstr = valstrtab + hashtable[hidx];
      while (isblank (*valstr))
	++valstr;

      if (strncmp (valstr, user, userlen) == 0 && isblank (valstr[userlen]))
	{
	  valstr += userlen + 1;
	  while (isblank (*valstr))
	    ++valstr;

	  while (*valstr != '\0')
	    {
	      errno = 0;
	      char *endp;
	      unsigned long int n = strtoul (valstr, &endp, 10);
	      if (*endp != ',' && *endp != '\0')
		break;
	      valstr = *endp == '\0' ? endp : endp + 1;

	      if (n != ULONG_MAX || errno != ERANGE)
		{
		  /* Insert the group.  */
		  if (*start == *size)
		    {
		      /* Need a bigger buffer.  */
		      if (limit > 0 && *size == limit)
			{
			  /* We reached the maximum.  */
			  status = NSS_STATUS_SUCCESS;
			  goto out;
			}

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

		      gid_t *newgroups = realloc (groups,
						  newsize * sizeof (*groups));
		      if (newgroups == NULL)
			{
			  *errnop = ENOMEM;
			  status = NSS_STATUS_TRYAGAIN;
			  goto out;
			}

		      *groupsp = groups = newgroups;
		      *size = newsize;
		    }

		  groups[*start] = n;
		  *start += 1;
		}
	    }

	  status = NSS_STATUS_SUCCESS;
	  break;
	}

      if ((hidx += hval2) >= header->dbs[i].hashsize)
	hidx -= header->dbs[i].hashsize;
    }

 out:
  internal_endent (&state);

  return status;
}
Example #6
0
enum nss_status _nss_filesplus_setgrent(void)
{
	NSS_DEBUG("filesplus: %s\n",__func__);

	return internal_setent(&fgrent);
}
Example #7
0
enum nss_status _nss_filesplus_initgroups_dyn(const char *user,
					      gid_t gid,
					      long int *start,
					      long int *size,
					      gid_t **groupsp,
					      long int limit,
					      int *errnop)
{
	enum nss_status result = NSS_STATUS_SUCCESS;
	struct group gr;
	char *buffer;
	size_t buffer_size;
	int found_one = 0;
	int i;

	gid_t *groups = *groupsp;

	NSS_DEBUG("filesplus: %s\n",__func__);

	result = internal_setent(&fgrent);
	if (result != NSS_STATUS_SUCCESS)
		return result;

	buffer_size = MAX_LINE_SIZE;
	buffer = (char *) malloc(buffer_size);

	while (result == NSS_STATUS_SUCCESS) {
		result = internal_getgrent(&gr, buffer, buffer_size,
					   errnop, NULL, NULL);

		if ((result == NSS_STATUS_TRYAGAIN) &&
		    ( *errnop == ERANGE)) {
			char *new_buf;
			buffer_size = 2 * buffer_size;
			new_buf = (char *) realloc(buffer, buffer_size);
			if (new_buf == NULL) {
				*errnop = errno;
				result = NSS_STATUS_UNAVAIL;
				break;
			}
			buffer = new_buf;
			*errnop = 0;
			result = NSS_STATUS_SUCCESS;
			continue;
		}

		if (result != NSS_STATUS_SUCCESS)
			continue;

		if (gr.gr_gid == gid)
			continue;

		for (i = 0; ; i++) {
			if (gr.gr_mem[i] == NULL)
				break;

			if (strcmp(gr.gr_mem[i], user) == 0) {
				/* Matches user.  Insert this group.  */
				if (*start == *size) {
					/* Need a bigger buffer.  */
					if (limit > 0 && *size == limit)
						/* We reached the maximum.  */
						goto out;

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

					gid_t *newgroups = realloc (groups,
								    newsize * sizeof (*groups));
					if (newgroups == NULL)
					{
						*errnop = ENOMEM;
						result = NSS_STATUS_TRYAGAIN;
						goto out;
					}
					*groupsp = groups = newgroups;
					*size = newsize;
				}
				groups[*start] = gr.gr_gid;
				*start += 1;
				found_one = 1;
				break;
			}
		}
	}

out:
	free(buffer);
	internal_endent(&fgrent);

	if (NSS_STATUS_NOTFOUND && found_one)
		result = NSS_STATUS_SUCCESS;

	return result;
}