Пример #1
1
static VALUE group_gr_put(VALUE self, VALUE io)
{
  struct group grp;
  VALUE path;
#ifdef HAVE_FGETGRENT
  struct group *tmp_grp;
  long i = 0;
#endif

  Check_EU_Type(self, rb_cGroup);
  Check_Writes(io, FMODE_WRITABLE);

  path = RFILE_PATH(io);

  rewind(RFILE_FPTR(io));
  grp.gr_name     = RSTRING_PTR(rb_ivar_get(self, id_name));

#ifdef HAVE_FGETGRENT
  while ( (tmp_grp = fgetgrent(RFILE_FPTR(io))) )
    if ( !strcmp(tmp_grp->gr_name, grp.gr_name) )
      rb_raise(rb_eArgError, "%s is already mentioned in %s:%ld",
	       tmp_grp->gr_name,  StringValuePtr(path), ++i );
#endif

  grp.gr_passwd = RSTRING_PTR(rb_ivar_get(self, id_passwd));
  grp.gr_gid    = NUM2GIDT( rb_ivar_get(self, id_gid) );
  grp.gr_mem    = setup_char_members( rb_iv_get(self, "@members") );

  if ( putgrent(&grp,RFILE_FPTR(io)) )
    eu_errno(RFILE_PATH(io));

  free_char_members(grp.gr_mem, (int)RARRAY_LEN( rb_iv_get(self, "@members") ));

  return Qtrue;
}
Пример #2
0
static void
test_fgetgrent (const char *filename)
{
  struct group *g;
  FILE *f;

  f = fopen (filename,"r");

  g = fgetgrent (f);
  test_entry ("one", 1, g);
  g = fgetgrent (f);
  test_entry ("two", 2, g);
  g = fgetgrent (f);
  test_entry ("three", 3, g);
  fclose (f);
}
Пример #3
0
/* make sure gr_name isn't taken, make sure gid is kosher
 * return 1 on failure */
static int group_study(const char *filename, struct group *g)
{
	FILE *etc_group;
	gid_t desired;

	struct group *grp;
	const int max = 65000;

	etc_group = bb_xfopen(filename, "r");

	/* make sure gr_name isn't taken, make sure gid is kosher */
	desired = g->gr_gid;
	while ((grp = fgetgrent(etc_group))) {
		if ((strcmp(grp->gr_name, g->gr_name)) == 0) {
			bb_error_msg_and_die("%s: group already in use\n", g->gr_name);
		}
		if ((desired) && grp->gr_gid == desired) {
			bb_error_msg_and_die("%d: gid has already been allocated\n",
							  desired);
		}
		if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) {
			g->gr_gid = grp->gr_gid;
		}
	}
	fclose(etc_group);

	/* gid */
	if (desired) {
		g->gr_gid = desired;
	} else {
		g->gr_gid++;
	}
	/* return 1; */
	return 0;
}
Пример #4
0
static struct group *af_getgrent(void) {
  struct group *grp = NULL, *res = NULL;

  if (!af_group_file ||
      !af_group_file->af_file) {
    errno = EINVAL;
    return NULL;
  }

  while (TRUE) {
#ifdef HAVE_FGETGRENT
    pr_signals_handle();
    grp = fgetgrent(af_group_file->af_file);
#else
    char *cp = NULL, *buf = NULL;
    int buflen = BUFSIZ;

    pr_signals_handle();

    buf = malloc(BUFSIZ);
    if (buf == NULL) {
      pr_log_pri(PR_LOG_CRIT, "%s", "Out of memory!");
      _exit(1);
    }
    grp = NULL;

    while (af_getgrentline(&buf, &buflen, af_group_file->af_file) != NULL) {

      /* Ignore comment and empty lines */
      if (buf[0] == '\0' ||
          buf[0] == '#') {
        continue;
      }

      cp = strchr(buf, '\n');
      if (cp != NULL)
        *cp = '\0';

      grp = af_getgrp(buf);
      free(buf);

      break;
    }
#endif /* !HAVE_FGETGRENT */

    /* If grp is NULL now, the file is empty - nothing more to be read. */
    if (grp == NULL) {
      break;
    }

    if (af_allow_grent(grp) < 0) {
      continue;
    }

    res = grp;
    break;
  }

  return res;
}
Пример #5
0
// the same as getgrouplist(), but it only parses /etc/group
int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
{
	int nr = 0, ret;
	FILE *file = fopen("/etc/group", "r");
	if (!file) {
		perror("faile to open /etc/group");
		return -1;
	}
	for (;;) {
		struct group *gr = fgetgrent(file);
		if (!gr)
			break;
		int j;
		for (j = 0; gr->gr_mem && gr->gr_mem[j]; j++) {
			if (!strcmp(gr->gr_mem[j], user)) {
				if (nr + 1 < *ngroups)
					groups[nr] = gr->gr_gid;
				nr++;
			}
		}
	}
	fclose(file);
	if (nr == 0) {
		if (nr + 1 < *ngroups)
			groups[nr] = group;
		nr++;
	}
	ret = nr <= *ngroups ? nr : -1;
	*ngroups = nr;
	return ret;
}
Пример #6
0
static struct group *p_getgrent(void) {
  struct group *gr = NULL;

  if (!grpf)
    p_setgrent();

  if (!grpf)
    return NULL;

  gr = fgetgrent(grpf);

  return gr;
}
Пример #7
0
int main()
{
	//从指定文件来读取组格式
	struct group *data;
	FILE *stream;
	int i;
	stream = fopen("/etc/group","r");
	while((data = fgetgrent(stream)) != 0)
	{
		int i;
		printf("%s:%s:%d:",data->gr_name,data->gr_passwd,data->gr_gid);
		while(data->gr_mem[i]) printf("%s,",data->gr_mem[i++]);
		printf("\n");
	}
	fclose(stream);
}
Пример #8
0
static bool GroupGetUserMembership (const char *user, StringSet *result)
{
    bool ret = true;
    struct group *group_info;

    FILE *fptr = fopen("/etc/group", "r");
    if (!fptr)
    {
        Log(LOG_LEVEL_ERR, "Could not open '/etc/group': %s", GetErrorStr());
        return false;
    }

    while (true)
    {
        errno = 0;
        // Use fgetgrent() instead of getgrent(), to guarantee that the
        // returned group is a local group, and not for example from LDAP.
        group_info = fgetgrent(fptr);
        if (!group_info)
        {
            // Documentation among Unices is conflicting on return codes. When there
            // are no more entries, this happens:
            // Linux = ENOENT
            // AIX = ESRCH
            if (errno && errno != ENOENT && errno != ESRCH)
            {
                Log(LOG_LEVEL_ERR, "Error while getting group list. (fgetgrent: '%s')", GetErrorStr());
                ret = false;
            }
            break;
        }
        for (int i = 0; group_info->gr_mem[i] != NULL; i++)
        {
            if (strcmp(user, group_info->gr_mem[i]) == 0)
            {
                StringSetAdd(result, xstrdup(group_info->gr_name));
                break;
            }
        }
    }

    fclose(fptr);

    return ret;
}
Пример #9
0
long my_getgrnam(const char *name)
{
	struct group *mygroup;
	FILE *stream;

	stream = bb_xfopen(GROUP_PATH, "r");
	while(1) {
		errno = 0;
		mygroup = fgetgrent(stream);
		if (mygroup == NULL)
			bb_error_msg_and_die("unknown group name: %s", name);
		if (errno)
			bb_perror_msg_and_die("fgetgrent");
		if (!strcmp(name, mygroup->gr_name))
			break;
	}
	fclose(stream);

	return mygroup->gr_gid;
}
Пример #10
0
// the same as getgrnam(), but it only parses /etc/group and allows the name to be id string
struct group *hyper_getgrnam(const char *name)
{
	gid_t gid = (gid_t)id_or_max(name);
	FILE *file = fopen("/etc/group", "r");
	if (!file) {
		perror("faile to open /etc/group");
		return NULL;
	}
	for (;;) {
		struct group *gr = fgetgrent(file);
		if (!gr)
			break;
		if (!strcmp(gr->gr_name, name) || gr->gr_gid == gid) {
			fclose(file);
			return gr;
		}
	}
	fclose(file);
	return NULL;
}
Пример #11
0
static GPtrArray *
data2groupents (const char *data)
{
  struct group *ent = NULL;
  _cleanup_stdio_file_ FILE *mf = NULL;
  GPtrArray *ret = g_ptr_array_new_with_free_func (conv_group_ent_free);
  
  mf = fmemopen ((void *)data, strlen (data), "r");
  
  while ((ent = fgetgrent (mf)))
    {
      struct conv_group_ent *convent = g_new (struct conv_group_ent, 1);

      convent->name = g_strdup (ent->gr_name);
      convent->gid  = ent->gr_gid;
      /* Want to add anymore, like users? */

      g_ptr_array_add (ret, convent);
    }

  return ret;
}
Пример #12
0
// Uses fgetgrent() instead of getgrnam(), to guarantee that the returned group
// is a local group, and not for example from LDAP.
static struct group *GetGrEntry(const char *key,
                                bool (*equal_fn)(const char *key, const struct group *entry))
{
    FILE *fptr = fopen("/etc/group", "r");
    if (!fptr)
    {
        Log(LOG_LEVEL_ERR, "Could not open '/etc/group': %s", GetErrorStr());
        return NULL;
    }

    struct group *group_info;
    bool found = false;
    while ((group_info = fgetgrent(fptr)))
    {
        if (equal_fn(key, group_info))
        {
            found = true;
            break;
        }
    }

    fclose(fptr);

    if (found)
    {
        return group_info;
    }
    else
    {
        // Failure to find the user means we just set errno to zero.
        // Perhaps not optimal, but we cannot pass ENOENT, because the fopen might
        // fail for this reason, and that should not be treated the same.
        errno = 0;
        return NULL;
    }
}
Пример #13
0
bool KGroups::load() {
  struct group *p;
  KGroup *tmpKG = 0;
  struct stat st;

  stat(GROUP_FILE, &st);
  mode = st.st_mode;
  uid = st.st_uid;
  gid = st.st_gid;

#ifdef HAVE_FGETGRENT
  FILE *fgrp = fopen(GROUP_FILE, "r");
  QString tmp;
  if (fgrp == 0) {
    ksprintf(&tmp, i18n("Error opening %s for reading"), GROUP_FILE);
    err->addMsg(tmp, STOP);
    return FALSE;
  }

  while ((p = fgetgrent(fgrp)) != NULL) {
#else
  while ((p = getgrent()) != NULL) {
#endif
    tmpKG = new KGroup();
    tmpKG->setGID(p->gr_gid);
    tmpKG->setName(p->gr_name);
    tmpKG->setPwd(p->gr_passwd);

    char *u_name;
    int i = 0;
    while ((u_name = p->gr_mem[i])!=0) {
      tmpKG->addUser(u_name);
      i++;
    }

    g.append(tmpKG);
  }

#ifdef HAVE_FGETGRENT
  fclose(fgrp);
#endif

  return TRUE;
}

bool KGroups::save() {
  FILE *grp;
  QString tmpS;
  QString tmpN;
  QString tmp;

  if (!g_saved) {
    backup(GROUP_FILE);
    g_saved = TRUE;
  }

  umask(0077);

  if ((grp = fopen(GROUP_FILE, "w")) == NULL) {
    ksprintf(&tmp, i18n("Error opening %s for writing"), GROUP_FILE);
    err->addMsg(tmp, STOP);
    return FALSE;
  }

  for (unsigned int i=0; i<g.count(); i++) {
    tmpN.setNum(g.at(i)->getGID());
    tmpS = g.at(i)->getName()+':'+g.at(i)->getPwd()+':'+tmpN+':';
    for (uint j=0; j<g.at(i)->count(); j++) {
       if (j != 0)
	 tmpS += ',';

       tmpS += g.at(i)->user(j);
    }
    tmpS += '\n';
    fputs(tmpS, grp);
  }
  fclose(grp);

  chmod(GROUP_FILE, mode);
  chown(GROUP_FILE, uid, gid);

#ifdef GRMKDB
  if (system(GRMKDB) != 0) {
    err->addMsg("Unable to build group database", STOP);
    return FALSE;
  }
#endif
  return (TRUE);
}
Пример #14
0
enum nss_status
_nss_map_initgroups_dyn (const char *user, gid_t group, long int *start,
		long int *size, gid_t **groupsp, long int limit, int *errnop)
{
	gid_t *groups = *groupsp;
	FILE *fp = NULL;
	map_conf_t *conf;
	char *dir;
	struct stat s;
	struct group *g;

	conf = read_conf();

	if (conf == NULL) {
		DEBUG("%s:%d:initgroups_dyn:unable to open configuration file (%s).\n",
				__FILE__, __LINE__, MAIN_CONF_FILE);
		return NSS_STATUS_UNAVAIL;
	}

	if (( dir = (char *)malloc( (strlen(user) + 1 +
						strlen(conf->pw_dir)  + 1 +
						strlen(MAIN_CONF_FILE)) * sizeof(char) ) ) == NULL)
	{
		DEBUG("%s:%d:initgroups_dyn:unable to adquire memory for config.\n",
				__FILE__, __LINE__);
		return NSS_STATUS_TRYAGAIN;
	}

	strcpy(dir, conf->pw_dir);
	strcat(dir,"/");
	strcat(dir,user);
	strcat(dir,"/");
	strcat(dir,USER_CONF_FILE);
	free_conf(conf);

	/* some security checking */
	if ( stat(dir, &s) == -1 )
		goto format_error;

	if ( ! S_ISREG(s.st_mode) )
		goto format_error;

	if ( (s.st_mode & S_IWGRP) || (s.st_mode & S_IWOTH) )
		goto format_error;

	if ( (s.st_uid) || (s.st_gid) )
		goto format_error;

	if ( (fp = fopen(dir, "r")) == NULL )
		goto format_error;

	if ( (g = fgetgrent(fp)) == NULL )
		goto format_error;
	else
		fclose(fp);

	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;
	}

	groups[(*start)++] = g->gr_gid;

done:
	return NSS_STATUS_SUCCESS;

format_error:
	if(fp != NULL) fclose(fp);
	free(dir);
    return NSS_STATUS_UNAVAIL;

}
Пример #15
0
struct group *_spfgetgrent(FILE *F) { return(_spsubsgrp(fgetgrent(F))); }