/* Copyright (c) 1997,1998,1999,2004,2005,2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <assert.h>
#include <string.h>
#include <rpcsvc/nis.h>

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 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, ".");
          stpcpy (cp, cp2);
        }
      res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME);
      if (res == NULL)
	return NIS_NOMEMORY;
      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_name *gr_members_val
	= NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_val;
      u_int gr_members_len
	= NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len;

      u_int j = 0;
      for (u_int i = 0; i < gr_members_len; ++i)
	if (strcmp (gr_members_val[i], member) != 0)
	  gr_members_val[j++] = gr_members_val[i];
	else
	  free (gr_members_val[i]);

      /* There is no need to reallocate the gr_members_val array.  We
	 just adjust the size to match the number of strings still in
	 it.  Yes, xdr_array will use mem_free with a size parameter
	 but this is mapped to a simple free call which determines the
	 size of the block by itself.  */
      NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len = j;

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