Пример #1
0
nis_error
nis_verifygroup (const_nis_name group)
{
  if (group != NULL && group[0] != '\0')
    {
      size_t grouplen = strlen (group);
      char buf[grouplen + 50];
      char leafbuf[grouplen + 2];
      char domainbuf[grouplen + 2];
      nis_result *res;
      nis_error status;
      char *cp, *cp2;

      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
      cp = stpcpy (cp, ".groups_dir");
      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
      if (cp2 != NULL && cp2[0] != '\0')
	{
	  *cp++ = '.';
	  stpcpy (cp, cp2);
	}
      res = nis_lookup (buf, 0);
      status = NIS_RES_STATUS (res);
      nis_freeresult (res);
      return status;
    }
  else
    return NIS_FAIL;
}
Пример #2
0
nis_result *
nis_checkpoint (const_nis_name dirname)
{
  nis_result *res;

  res = calloc (1, sizeof (nis_result));
  if (res == NULL)
    return NULL;

  if (dirname != NULL)
    {
      nis_result *res2;
      u_int i;

      res2 = nis_lookup (dirname, EXPAND_NAME);
      if (NIS_RES_STATUS (res2) != NIS_SUCCESS)
	{
	  free (res);
	  return res2;
	}

      /* Check if obj is really a diryectory object */
      if (__type_of (NIS_RES_OBJECT (res2)) != NIS_DIRECTORY_OBJ)
	{
	  nis_freeresult (res2);
	  NIS_RES_STATUS (res) = NIS_INVALIDOBJ;
	  return res;
	}

      for (i = 0;
	   i < NIS_RES_OBJECT (res2)->DI_data.do_servers.do_servers_len; ++i)
	{
	  cp_result cpres;

	  memset (&cpres, '\0', sizeof (cp_result));
	  if (__do_niscall2 (&NIS_RES_OBJECT(res2)->DI_data.do_servers.do_servers_val[i],
			     1, NIS_CHECKPOINT, (xdrproc_t) _xdr_nis_name,
			     (caddr_t) &dirname, (xdrproc_t) _xdr_cp_result,
			     (caddr_t) &cpres, 0, NULL) != NIS_SUCCESS)
	    NIS_RES_STATUS (res) = NIS_RPCERROR;
	  else
	    {
	      NIS_RES_STATUS (res) = cpres.cp_status;
	      res->zticks += cpres.cp_zticks;
	      res->dticks += cpres.cp_dticks;
	    }
	}
      nis_freeresult (res2);
    }
  else
    NIS_RES_STATUS (res) = NIS_NOSUCHNAME;

  return res;
}
Пример #3
0
int
nisplus_init(mnt_map *m, char *map, time_t *tp)
{
  nis_result *result;
  char *org;		/* if map does not have ".org_dir" then append it */
  nis_name map_name;
  int error = 0;
  size_t l;

  org = strstr(map, NISPLUS_ORGDIR);
  if (org == NULL)
    org = NISPLUS_ORGDIR;
  else
    org = "";

  /* make some room for the NIS map_name */
  l = strlen(map) + sizeof(NISPLUS_ORGDIR);
  map_name = xmalloc(l);
  if (map_name == NULL) {
    plog(XLOG_ERROR,
	 "Unable to create map_name %s: %s",
	 map,
	 strerror(ENOMEM));
    return ENOMEM;
  }
  xsnprintf(map_name, l, "%s%s", map, org);

  result = nis_lookup(map_name, (EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH));

  /* free off the NIS map_name */
  XFREE(map_name);

  if (result == NULL) {
    plog(XLOG_ERROR, "NISplus init <%s>: %s", map, strerror(ENOMEM));
    return ENOMEM;
  }

  if (result->status != NIS_SUCCESS) {
    dlog("NISplus init <%s>: %s (%d)",
	 map, nis_sperrno(result->status), result->status);

    error = ENOENT;
  }

  *tp = 0;			/* no time */
  nis_freeresult(result);
  return error;
}
Пример #4
0
void
nis_ping (const_nis_name dirname, unsigned int utime,
	  const nis_object *dirobj)
{
  nis_result *res = NULL;
  nis_object *obj;
  ping_args args;
  unsigned int i;

  if (dirname == NULL && dirobj == NULL)
    abort ();

  if (dirobj == NULL)
    {
      res = nis_lookup (dirname, MASTER_ONLY);
      if (res == NULL || NIS_RES_STATUS (res) != NIS_SUCCESS)
	{
	  nis_freeresult (res);
	  return;
	}
      obj = res->objects.objects_val;
    }
  else
    obj = (nis_object *) dirobj;

  /* Check if obj is really a diryectory object */
  if (__type_of (obj) != NIS_DIRECTORY_OBJ)
    {
      nis_freeresult (res);
      return;
    }

  if (dirname == NULL)
    args.dir = obj->DI_data.do_name;
  else
    args.dir = (char *) dirname;
  args.stamp = utime;

  /* Send the ping only to replicas */
  for (i = 1; i < obj->DI_data.do_servers.do_servers_len; ++i)
    __do_niscall2 (&obj->DI_data.do_servers.do_servers_val[i], 1,
		   NIS_PING, (xdrproc_t) _xdr_ping_args,
		   (caddr_t) &args, (xdrproc_t) xdr_void,
		   (caddr_t) NULL, 0, NULL);
  nis_freeresult (res);
}
nis_error
nis_removemember (const_nis_name member, const_nis_name group)
{
  if (group != NULL && group[0] != '\0')
    {
      size_t grouplen = strlen (group);
      char buf[grouplen + 14 + NIS_MAXNAMELEN];
      char leafbuf[grouplen + 2];
      char domainbuf[grouplen + 2];
      nis_name *newmem;
      nis_result *res, *res2;
      nis_error status;
      char *cp, *cp2;
      unsigned long int i, j, k;

      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
      cp = stpcpy (cp, ".groups_dir");
      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
      if (cp2 != NULL && cp2[0] != '\0')
        {
          cp = stpcpy (cp, ".");
          stpcpy (cp, cp2);
        }
      res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME);
      if (res == NULL || NIS_RES_STATUS (res) != NIS_SUCCESS)
        {
	  if (res)
	    {
	      status = NIS_RES_STATUS (res);
	      nis_freeresult (res);
	    }
	  else
	    return NIS_NOMEMORY;
          return status;
        }

      if ((res->objects.objects_len != 1) ||
          (__type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ))
	{
	  nis_freeresult (res);
	  return NIS_INVALIDOBJ;
	}

      newmem =
	calloc (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len,
		sizeof (char *));
      if (newmem == NULL)
	return NIS_NOMEMORY;

      k = NIS_RES_OBJECT (res)[0].GR_data.gr_members.gr_members_len;
      j = 0;
      for (i = 0; i < NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len;
	   ++i)
	{
	  if (strcmp (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val[i],
		      member) != 0)
	    {
	      newmem[j] = NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val[i];
	      ++j;
	    }
	  else
	    {
	      free (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val[i]);
	      --k;
	    }
	}
      free (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val);
      newmem = realloc (newmem, k * sizeof (char*));
      if (newmem == NULL)
	return NIS_NOMEMORY;

      NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val = newmem;
      NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len = k;

      cp = stpcpy (buf, NIS_RES_OBJECT (res)->zo_name);
      *cp++ = '.';
      strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN);
      res2 = nis_modify (buf, NIS_RES_OBJECT (res));
      status = NIS_RES_STATUS (res2);
      nis_freeresult (res);
      nis_freeresult (res2);

      return status;
    }
  else
    return NIS_FAIL;
}
void
nis_print_group_entry (const_nis_name group)
{
    if (group != NULL && group[0] != '\0')
    {
        size_t grouplen = strlen (group);
        char buf[grouplen + 50];
        char leafbuf[grouplen + 3];
        char domainbuf[grouplen + 3];
        nis_result *res;
        char *cp, *cp2;
        u_int i;

        cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
        cp = stpcpy (cp, ".groups_dir");
        cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
        if (cp2 != NULL && cp2[0] != '\0')
        {
            *cp++ = '.';
            stpcpy (cp, cp2);
        }
        res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME);

        if (res == NULL)
            return;

        if (NIS_RES_STATUS (res) != NIS_SUCCESS
                || NIS_RES_NUMOBJ (res) != 1
                || __type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ)
        {
            nis_freeresult (res);
            return;
        }

        char *mem_exp[NIS_RES_NUMOBJ (res)];
        char *mem_imp[NIS_RES_NUMOBJ (res)];
        char *mem_rec[NIS_RES_NUMOBJ (res)];
        char *nomem_exp[NIS_RES_NUMOBJ (res)];
        char *nomem_imp[NIS_RES_NUMOBJ (res)];
        char *nomem_rec[NIS_RES_NUMOBJ (res)];
        unsigned long mem_exp_cnt = 0, mem_imp_cnt = 0, mem_rec_cnt = 0;
        unsigned long nomem_exp_cnt = 0, nomem_imp_cnt = 0, nomem_rec_cnt = 0;

        for (i = 0;
                i < NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; ++i)
        {
            char *grmem =
                NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i];
            int neg = grmem[0] == '-';

            switch (grmem[neg])
            {
            case '*':
                if (neg)
                {
                    nomem_imp[nomem_imp_cnt] = grmem;
                    ++nomem_imp_cnt;
                }
                else
                {
                    mem_imp[mem_imp_cnt] = grmem;
                    ++mem_imp_cnt;
                }
                break;
            case '@':
                if (neg)
                {
                    nomem_rec[nomem_rec_cnt] = grmem;
                    ++nomem_rec_cnt;
                }
                else
                {
                    mem_rec[mem_rec_cnt] = grmem;
                    ++mem_rec_cnt;
                }
                break;
            default:
                if (neg)
                {
                    nomem_exp[nomem_exp_cnt] = grmem;
                    ++nomem_exp_cnt;
                }
                else
                {
                    mem_exp[mem_exp_cnt] = grmem;
                    ++mem_exp_cnt;
                }
                break;
            }
        }
        {
            char buf[strlen (NIS_RES_OBJECT (res)->zo_domain) + 10];
            printf (_("Group entry for \"%s.%s\" group:\n"),
                    NIS_RES_OBJECT (res)->zo_name,
                    nis_domain_of_r (NIS_RES_OBJECT (res)->zo_domain,
                                     buf, strlen (NIS_RES_OBJECT (res)->zo_domain)
                                     + 10));
        }
        if (mem_exp_cnt)
        {
            fputs (_("    Explicit members:\n"), stdout);
            for (i = 0; i < mem_exp_cnt; ++i)
                printf ("\t%s\n", mem_exp[i]);
        }
        else
            fputs (_("    No explicit members\n"), stdout);
        if (mem_imp_cnt)
        {
            fputs (_("    Implicit members:\n"), stdout);
            for (i = 0; i < mem_imp_cnt; ++i)
                printf ("\t%s\n", &mem_imp[i][2]);
        }
        else
            fputs (_("    No implicit members\n"), stdout);
        if (mem_rec_cnt)
        {
            fputs (_("    Recursive members:\n"), stdout);
            for (i = 0; i < mem_rec_cnt; ++i)
                printf ("\t%s\n", &mem_rec[i][1]);
        }
        else
            fputs (_("    No recursive members\n"), stdout);
        if (nomem_exp_cnt)
        {
            fputs (_("    Explicit nonmembers:\n"), stdout);
            for (i = 0; i < nomem_exp_cnt; ++i)
                printf ("\t%s\n", &nomem_exp[i][1]);
        }
        else
            fputs (_("    No explicit nonmembers\n"), stdout);
        if (nomem_imp_cnt)
        {
            fputs (_("    Implicit nonmembers:\n"), stdout);
            for (i = 0; i < nomem_imp_cnt; ++i)
                printf ("\t%s\n", &nomem_imp[i][3]);
        }
        else
            fputs (_("    No implicit nonmembers\n"), stdout);
        if (nomem_rec_cnt)
        {
            fputs (_("    Recursive nonmembers:\n"), stdout);
            for (i = 0; i < nomem_rec_cnt; ++i)
                printf ("\t%s=n", &nomem_rec[i][2]);
        }
        else
            fputs (_("    No recursive nonmembers\n"), stdout);

        nis_freeresult (res);
    }
}
Пример #7
0
nis_error
nis_addmember (const_nis_name member, const_nis_name group)
{
  if (group != NULL && group[0] != '\0')
    {
      size_t grouplen = strlen (group);
      char buf[grouplen + 14 + NIS_MAXNAMELEN];
      char domainbuf[grouplen + 2];
      nis_result *res, *res2;
      nis_error status;
      char *cp, *cp2;

      cp = rawmemchr (nis_leaf_of_r (group, buf, sizeof (buf) - 1), '\0');
      cp = stpcpy (cp, ".groups_dir");
      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
      if (cp2 != NULL && cp2[0] != '\0')
        {
	  *cp++ = '.';
          stpcpy (cp, cp2);
        }
      res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME);
      if (NIS_RES_STATUS (res) != NIS_SUCCESS)
	{
	  status = NIS_RES_STATUS (res);
	  nis_freeresult (res);
	  return status;
	}
      if (NIS_RES_NUMOBJ (res) != 1
	  || __type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ)
	{
	  nis_freeresult (res);
	  return NIS_INVALIDOBJ;
	}

      u_int gr_members_len
	= NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len;

      nis_name *new_gr_members_val
	= realloc (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val,
		   (gr_members_len + 1) * sizeof (nis_name));
      if (new_gr_members_val == NULL)
	goto nomem_out;

      NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val
	= new_gr_members_val;

      new_gr_members_val[gr_members_len] = strdup (member);
      if (new_gr_members_val[gr_members_len] == NULL)
	{
	nomem_out:
	  nis_freeresult (res);
	  return NIS_NOMEMORY;
	}
      ++NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len;

      /* Check the buffer bounds are not exceeded.  */
      assert (strlen (NIS_RES_OBJECT(res)->zo_name) + 1 < grouplen + 14);
      cp = stpcpy (buf, NIS_RES_OBJECT(res)->zo_name);
      *cp++ = '.';
      strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN);
      res2 = nis_modify (buf, NIS_RES_OBJECT (res));
      status = NIS_RES_STATUS (res2);
      nis_freeresult (res);
      nis_freeresult (res2);

      return status;
    }
  else
    return NIS_FAIL;
}
Пример #8
0
static int
nisplus_find(void *handle, uschar *filename, uschar *query, int length,
  uschar **result, uschar **errmsg, uint *do_cache)
{
int i;
int ssize = 0;
int offset = 0;
int error_error = FAIL;
uschar *field_name = NULL;
nis_result *nrt = NULL;
nis_result *nre = NULL;
nis_object *tno, *eno;
struct entry_obj *eo;
struct table_obj *ta;
uschar *p = query + length;
uschar *yield = NULL;

do_cache = do_cache;   /* Placate picky compilers */

/* Search backwards for a colon to see if a result field name
has been given. */

while (p > query && p[-1] != ':') p--;

if (p > query)
  {
  field_name = p;
  p[-1] = 0;
  }
else p = query + length;

/* Now search backwards to find the comma that starts the
table name. */

while (p > query && p[-1] != ',') p--;
if (p <= query)
  {
  *errmsg = US"NIS+ query malformed";
  error_error = DEFER;
  goto NISPLUS_EXIT;
  }

/* Look up the data for the table, in order to get the field names,
check that we got back a table, and set up pointers so the field
names can be scanned. */

nrt = nis_lookup(CS p, EXPAND_NAME | NO_CACHE);
if (nrt->status != NIS_SUCCESS)
  {
  *errmsg = string_sprintf("NIS+ error accessing %s table: %s", p,
    nis_sperrno(nrt->status));
  if (nrt->status != NIS_NOTFOUND && nrt->status != NIS_NOSUCHTABLE)
    error_error = DEFER;
  goto NISPLUS_EXIT;
  }
tno = nrt->objects.objects_val;
if (tno->zo_data.zo_type != TABLE_OBJ)
  {
  *errmsg = string_sprintf("NIS+ error: %s is not a table", p);
  goto NISPLUS_EXIT;
  }
ta = &(tno->zo_data.objdata_u.ta_data);

/* Now look up the entry in the table, check that we got precisely one
object and that it is a table entry. */

nre = nis_list(CS query, EXPAND_NAME, NULL, NULL);
if (nre->status != NIS_SUCCESS)
  {
  *errmsg = string_sprintf("NIS+ error accessing entry %s: %s",
    query, nis_sperrno(nre->status));
  goto NISPLUS_EXIT;
  }
if (nre->objects.objects_len > 1)
  {
  *errmsg = string_sprintf("NIS+ returned more than one object for %s",
    query);
  goto NISPLUS_EXIT;
  }
else if (nre->objects.objects_len < 1)
  {
  *errmsg = string_sprintf("NIS+ returned no data for %s", query);
  goto NISPLUS_EXIT;
  }
eno = nre->objects.objects_val;
if (eno->zo_data.zo_type != ENTRY_OBJ)
  {
  *errmsg = string_sprintf("NIS+ error: %s is not an entry", query);
  goto NISPLUS_EXIT;
  }

/* Scan the columns in the entry and in the table. If a result field
was given, look for that field; otherwise concatenate all the fields
with their names. */

eo = &(eno->zo_data.objdata_u.en_data);
for (i = 0; i < eo->en_cols.en_cols_len; i++)
  {
  table_col *tc = ta->ta_cols.ta_cols_val + i;
  entry_col *ec = eo->en_cols.en_cols_val + i;
  int len = ec->ec_value.ec_value_len;
  uschar *value = US ec->ec_value.ec_value_val;

  /* The value may be NULL for a zero-length field. Turn this into an
  empty string for consistency. Remove trailing whitespace and zero
  bytes. */

  if (value == NULL) value = US""; else
    while (len > 0 && (value[len-1] == 0 || isspace(value[len-1])))
      len--;

  /* Concatenate all fields if no specific one selected */

  if (field_name == NULL)
    {
    yield = string_cat(yield, &ssize, &offset,US  tc->tc_name,
      Ustrlen(tc->tc_name));
    yield = string_cat(yield, &ssize, &offset, US"=", 1);

    /* Quote the value if it contains spaces or is empty */

    if (value[0] == 0 || Ustrchr(value, ' ') != NULL)
      {
      int j;
      yield = string_cat(yield, &ssize, &offset, US"\"", 1);
      for (j = 0; j < len; j++)
        {
        if (value[j] == '\"' || value[j] == '\\')
          yield = string_cat(yield, &ssize, &offset, US"\\", 1);
        yield = string_cat(yield, &ssize, &offset, value+j, 1);
        }
      yield = string_cat(yield, &ssize, &offset, US"\"", 1);
      }
    else yield = string_cat(yield, &ssize, &offset, value, len);

    yield = string_cat(yield, &ssize, &offset, US" ", 1);
    }

  /* When the specified field is found, grab its data and finish */

  else if (Ustrcmp(field_name, tc->tc_name) == 0)
    {
    yield = string_copyn(value, len);
    goto NISPLUS_EXIT;
    }
  }

/* Error if a field name was specified and we didn't find it; if no
field name, ensure the concatenated data is zero-terminated. */

if (field_name != NULL)
  *errmsg = string_sprintf("NIS+ field %s not found for %s", field_name,
    query);
else
  {
  yield[offset] = 0;
  store_reset(yield + offset + 1);
  }

/* Restore the colon in the query, and free result store before
finishing. */

NISPLUS_EXIT:
if (field_name != NULL) field_name[-1] = ':';
if (nrt != NULL) nis_freeresult(nrt);
if (nre != NULL) nis_freeresult(nre);

if (yield != NULL)
  {
  *result = yield;
  return OK;
  }

return error_error;      /* FAIL or DEFER */
}
Пример #9
0
nis_error
nis_addmember (const_nis_name member, const_nis_name group)
{
  if (group != NULL && group[0] != '\0')
    {
      size_t grouplen = strlen (group);
      char buf[grouplen + 14 + NIS_MAXNAMELEN];
      char leafbuf[grouplen + 2];
      char domainbuf[grouplen + 2];
      nis_result *res, *res2;
      nis_error status;
      char *cp, *cp2;

      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
      cp = stpcpy (cp, ".groups_dir");
      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
      if (cp2 != NULL && cp2[0] != '\0')
        {
	  *cp++ = '.';
          stpcpy (cp, cp2);
        }
      res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME);
      if (NIS_RES_STATUS (res) != NIS_SUCCESS)
	{
	  status = NIS_RES_STATUS (res);
	  nis_freeresult (res);
	  return status;
	}
      if ((NIS_RES_NUMOBJ (res)  != 1) ||
          (__type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ))
	{
	  nis_freeresult (res);
	  return NIS_INVALIDOBJ;
	}

      NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val
	= realloc (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val,
		   (NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len + 1)
		   * sizeof (char *));
      if (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val == NULL)
	goto nomem_out;
      NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len] = strdup (member);
      if (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len] == NULL)
	{
	  free (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val);
	nomem_out:
	  nis_freeresult (res);
	  return NIS_NOMEMORY;
	}
      ++NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len;

      cp = stpcpy (buf, NIS_RES_OBJECT(res)->zo_name);
      *cp++ = '.';
      strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN);
      res2 = nis_modify (buf, NIS_RES_OBJECT (res));
      status = NIS_RES_STATUS (res2);
      nis_freeresult (res);
      nis_freeresult (res2);

      return status;
    }
  else
    return NIS_FAIL;
}
Пример #10
0
/* internal_nis_ismember ()
   return codes: -1 principal is in -group
                  0 principal isn't in any group
		  1 pirncipal is in group */
static int
internal_ismember (const_nis_name principal, const_nis_name group)
{
  size_t grouplen = strlen (group);
  char buf[grouplen + 50];
  char leafbuf[grouplen + 2];
  char domainbuf[grouplen + 2];
  nis_result *res;
  char *cp, *cp2;
  u_int i;

  cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
  cp = stpcpy (cp, ".groups_dir");
  cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
  if (cp2 != NULL && cp2[0] != '\0')
    {
      *cp++ = '.';
      strcpy (cp, cp2);
    }

  res = nis_lookup (buf, EXPAND_NAME|FOLLOW_LINKS);
  if (res == NULL || NIS_RES_STATUS (res) != NIS_SUCCESS)
    {
      nis_freeresult (res);
      return 0;
    }

  if ((NIS_RES_NUMOBJ (res) != 1)
      || (__type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ))
    {
      nis_freeresult (res);
      return 0;
    }

  /* We search twice in the list, at first, if we have the name
     with a "-", then if without. "-member" has priority */
  for (i = 0; i < NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len; ++i)
    {
      cp = NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i];
      if (cp[0] == '-')
	{
	  if (strcmp (&cp[1], principal) == 0)
	    {
	      nis_freeresult (res);
	      return -1;
	    }
	  if (cp[1] == '@')
	    switch (internal_ismember (principal, &cp[2]))
	      {
	      case -1:
		nis_freeresult (res);
		return -1;
	      case 1:
		nis_freeresult (res);
		return 1;
	      default:
		break;
	      }
	  else
	    if (cp[1] == '*')
	      {
		char buf1[strlen (principal) + 2];
		char buf2[strlen (cp) + 2];

		if (strcmp (nis_domain_of_r (principal, buf1, sizeof buf1),
			    nis_domain_of_r (cp, buf2, sizeof buf2)) == 0)
		  {
		    nis_freeresult (res);
		    return -1;
		  }
	      }
	}
    }

  for (i = 0; i < NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; ++i)
    {
      cp = NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i];
      if (cp[0] != '-')
	{
	  if (strcmp (cp, principal) == 0)
	    {
	      nis_freeresult (res);
	      return 1;
	    }
	  if (cp[0] == '@')
	    switch (internal_ismember (principal, &cp[1]))
	      {
	      case -1:
		nis_freeresult (res);
		return -1;
	      case 1:
		nis_freeresult (res);
		return 1;
	      default:
		break;
	      }
	  else
	    if (cp[0] == '*')
	      {
		char buf1[strlen (principal) + 2];
		char buf2[strlen (cp) + 2];

		if (strcmp (nis_domain_of_r (principal, buf1, sizeof buf1),
			    nis_domain_of_r (cp, buf2, sizeof buf2)) == 0)
		  {
		    nis_freeresult (res);
		    return 1;
		  }
	      }
	}
    }
  nis_freeresult (res);
  return 0;
}