/* Copyright (C) 2000,2001,2002 Manuel Amador (Rudd-O)
   This file is part of Directory administrator.

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

   Directory administrator 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with Directory administrator; if not, send e-mail to amador@alomega.com
*/


#include "charset.h"
#include <glib.h>
#include <gnome.h>
#include "appsupport.h"
#include "groups.h"
#include "charset.h"
#include "dir_entry.h"
#include "appglobals.h"
#include "appfunctions.h"

///TODAS LAS FUNCIONES RETORNAN REFERENCIAS A SUS ETRUCTURAS INTERNAS, PERO SACAN
///COPIAS DE LOS STRINGS PASADOS PARA GUARDARLOS.  ESTOS DATOS SE DESTRUYEN AL LLAMAR
///A LAS FUNCIONES DESTROY
///OTROS TIPOS DE ESTRUCTURAS COMO LISTAS, NO SE COPIAN, SOLO SE GUARDAN REFERENCIAS

gchar *group_handled_objectclasses[] = {
"top","groupOfNames","posixGroup", NULL
};


void
g_debug_free (gpointer data)
{
  g_print ("\ng_debug_free: freeing element containing %s\n",(char*)data);
  g_free (data);
}



diradmin_group *
diradmin_group_new (gchar * dn,
		    gchar * cn, gchar * gidnumber)
{

  diradmin_group *conn = NULL;

  conn = g_new (diradmin_group, 1);
  conn->diradmin_group_data = NULL;
  conn->diradmin_group_members = NULL;
  conn->diradmin_group_dnmembers = NULL;
  conn->diradmin_group_objectclasses = NULL;

  diradmin_group_set_attribute (conn, "dn", cn);
  diradmin_group_set_attribute (conn, "cn", cn);
  diradmin_group_set_attribute (conn, "gidnumber", gidnumber);

  diradmin_group_set_members (conn, NULL);
  diradmin_group_set_dnmembers (conn, NULL);

  conn->diradmin_group_objectclasses =
    g_list_append (conn->diradmin_group_objectclasses, g_strdup ("top"));
  conn->diradmin_group_objectclasses =
    g_list_append (conn->diradmin_group_objectclasses,
		   g_strdup ("posixGroup"));

  return conn;
}

diradmin_group *
diradmin_group_duplicate (diradmin_group * tobeduped)
{

  diradmin_group *conn = NULL;
g_assert(tobeduped);
  conn = g_new (diradmin_group, 1);
  conn->diradmin_group_data = NULL;
  conn->diradmin_group_members = NULL;
  conn->diradmin_group_dnmembers = NULL;

  conn->diradmin_group_data =
    pairs_list_duplicate (tobeduped->diradmin_group_data);

  if (tobeduped->diradmin_group_members)
  diradmin_group_set_members (conn, tobeduped->diradmin_group_members);
  if (tobeduped->diradmin_group_dnmembers)
  diradmin_group_set_dnmembers (conn, tobeduped->diradmin_group_dnmembers);


  return conn;

}


void
diradmin_group_destroy (diradmin_group * todestroy)
{
  if (todestroy)
    {
      pairs_list_destroy (todestroy->diradmin_group_data);
      diradmin_group_set_members (todestroy, NULL);
      diradmin_group_set_dnmembers (todestroy, NULL);
      g_free (todestroy);
    }

}


gchar *
diradmin_group_get_attribute (diradmin_group * conn, gchar * attr)
{
//  return "hola";
  g_assert (conn);
  g_assert (conn->diradmin_group_data);
  g_assert (attr);
  return pairs_list_get_attribute (conn->diradmin_group_data, attr);
}

void
diradmin_group_set_attribute (diradmin_group * conn, gchar * attr, gchar * to)
{
  g_assert (attr);
  conn->diradmin_group_data =
    pairs_list_set_attribute (conn->diradmin_group_data, attr, to);
}

void
diradmin_group_remove_attribute (diradmin_group * conn, gchar * attr)
{
  conn->diradmin_group_data =
    pairs_list_remove_attribute (conn->diradmin_group_data, attr);
}

GList *
diradmin_group_get_members (diradmin_group * conn)
{
  //return a reference to the members list.  shouldnt be manipulated outside.
  return g_list_first (conn->diradmin_group_members);
}

GList *
diradmin_group_get_dnmembers (diradmin_group * conn)
{
  //return a reference to the members list.  shouldnt be manipulated outside.
  return g_list_first (conn->diradmin_group_dnmembers);
}

void
diradmin_group_add_member (diradmin_group * conn, gchar * member)
{

  dir_entry* userDN = NULL;

  diradmin_group_remove_member (conn, member);
  conn->diradmin_group_members =
    g_list_append (conn->diradmin_group_members, g_strdup (member));

  userDN = dir_entry_list_getbyuid (cached_dir_entries, member);
  if (userDN) {
     g_assert(dir_entry_get_dn(userDN));
     diradmin_group_add_dnmember(conn,dir_entry_get_dn(userDN));
  }

}

void
diradmin_group_add_dnmember (diradmin_group * conn, gchar * member)
{
  g_assert(member);
  diradmin_group_remove_dnmember (conn, member);
  conn->diradmin_group_dnmembers =
    g_list_append (conn->diradmin_group_dnmembers, g_strdup (member));
  diradmin_group_add_objectclass (conn, "groupOfNames");

}

/*void diradmin_group_dump_dnmembers(diradmin_group*conn) {
	GList* loopix;
	g_print("DN member dump of %s:\n",diradmin_group_get_attribute(conn,"dn"));
	for (loopix=g_list_first(conn->diradmin_group_members);loopix;loopix=loopix->next) {
		g_print("    Member: %s\n",loopix->data);
	}

}

void diradmin_group_dump_members(diradmin_group*conn) {
	GList* loopix;
	g_print("Unix member dump of %s:\n",diradmin_group_get_attribute(conn,"dn"));
	for (loopix=g_list_first(conn->diradmin_group_members);loopix;loopix=loopix->next) {
		g_print("    Member: %s\n",loopix->data);
	}

}
*/
void
diradmin_group_remove_member (diradmin_group * conn, gchar * member)
{

  GList *iterator = NULL;
  dir_entry* userDN;

  iterator = g_list_find_custom (conn->diradmin_group_members,
				 member, (GCompareFunc) g_strcasecmp);
  if (iterator)
    {
      conn->diradmin_group_members =
	g_list_remove_link (conn->diradmin_group_members, iterator);
      g_free (iterator->data);
      g_list_free_1 (iterator);
    }

  userDN = dir_entry_list_getbyuid (cached_dir_entries, member);
  if (userDN) {
     g_assert(dir_entry_get_dn(userDN));
     diradmin_group_add_dnmember(conn,dir_entry_get_dn(userDN));
  }


}

void
diradmin_group_remove_dnmember (diradmin_group * conn, gchar * member)
{
  GList *iterator = NULL;

  g_assert(member);

  iterator = g_list_find_custom (conn->diradmin_group_dnmembers,
				 member, (GCompareFunc) g_strcasecmp);
  if (iterator)
    {
      conn->diradmin_group_dnmembers =
	g_list_remove_link (conn->diradmin_group_dnmembers, iterator);
      g_free (iterator->data);
      g_list_free_1 (iterator);
    }

  if (g_list_length (conn->diradmin_group_dnmembers) == 0)
    diradmin_group_remove_objectclass (conn, "groupOfNames");

}



gboolean
diradmin_group_has_member (diradmin_group * conn, gchar * allowedserver)
{
  gchar *data;
  GList *iterator = NULL;
  iterator = g_list_first (conn->diradmin_group_members);
  while (iterator)
    {
      data = iterator->data;
      if (strcmp(allowedserver, iterator->data) == 0)
	{
	  return (TRUE);
	}
      iterator = g_list_next (iterator);
    }
  return (FALSE);
}

gboolean
diradmin_group_has_dnmember (diradmin_group * conn, gchar * allowedserver)
{
  gchar *data;
  GList *iterator = NULL;
  iterator = g_list_first (conn->diradmin_group_dnmembers);
  while (iterator)
    {
      data = iterator->data;
      if (g_strcasecmp (allowedserver, iterator->data) == 0)
	{
	  return (TRUE);
	}
      iterator = g_list_next (iterator);
    }
  return (FALSE);
}


void
diradmin_group_set_members (diradmin_group * conn, GList * memberlist)
{
  //removes all memberss in the list.  that means frees its allocated storage.

  GList *newmembers = NULL;
  GList *members = NULL;


  //free the old members list
  members = g_list_first (diradmin_group_get_members (conn));
  while (members)
    {
      g_free (members->data);
      members = g_list_next (members);
    }
  g_list_free (g_list_first (diradmin_group_get_members (conn)));

  //make a copy of the passed members list into newmembers
  members = g_list_first (memberlist);
  while (members)
    {
      newmembers = g_list_append (newmembers, g_strdup (members->data));
      members = g_list_next (members);
    }

  conn->diradmin_group_members = newmembers;
}

void
diradmin_group_set_dnmembers (diradmin_group * conn, GList * memberlist)
{
  //removes all memberss in the list.  that means frees its allocated storage.

  GList *newmembers = NULL;
  GList *members = NULL;

  //free the old members list
  members = g_list_first (diradmin_group_get_dnmembers (conn));
  while (members)
    {
      g_free (members->data);
      members = g_list_next (members);
    }
  g_list_free (g_list_first (diradmin_group_get_dnmembers (conn)));

  //make a copy of the passed members list into newmembers
  members = g_list_first (memberlist);
  while (members)
    {
      newmembers = g_list_append (newmembers, g_strdup (members->data));
      members = g_list_next (members);
    }

  conn->diradmin_group_dnmembers = newmembers;
}




//objectclasses
GList *
diradmin_group_get_objectclasses (diradmin_group * conn)
{
  //return a reference to the allowedservers list.  shouldnt be manipulated outside.
  return g_list_first (conn->diradmin_group_objectclasses);
}

void
diradmin_group_add_objectclass (diradmin_group * conn, gchar * allowedserver)
{
  int i;
//  gboolean si = FALSE;

  diradmin_group_remove_objectclass (conn, allowedserver);

  for (i = 0;group_handled_objectclasses[i];i++) {
    if (g_strcasecmp(group_handled_objectclasses[i],allowedserver) == 0)
      conn->diradmin_group_objectclasses =
              g_list_append (conn->diradmin_group_objectclasses,
			   g_strdup (allowedserver));

  }
}

void
diradmin_group_remove_objectclass (diradmin_group * conn,
				   gchar * allowedserver)
{
  GList *iterator = NULL;


	for (iterator = g_list_first(conn->diradmin_group_objectclasses);iterator;iterator=iterator->next)
		if (g_strcasecmp(iterator->data,allowedserver)==0)
		{
			conn->diradmin_group_objectclasses =
			g_list_remove_link (conn->diradmin_group_objectclasses, iterator);
			g_free (iterator->data);
			g_list_free_1 (iterator);
			iterator =g_list_first(conn->diradmin_group_objectclasses);
		}
}


gboolean
diradmin_group_has_objectclass (diradmin_group * conn, gchar * allowedserver)
{
  gchar *data;
  GList *iterator = NULL;
  iterator = g_list_first (conn->diradmin_group_objectclasses);
  while (iterator)
    {
      data = iterator->data;
      if (g_strcasecmp (allowedserver, iterator->data) == 0)
	{
	  return (TRUE);
	}
      iterator = g_list_next (iterator);
    }
  return (FALSE);
}



void
diradmin_group_set_objectclasses (diradmin_group * conn, GList
				  * allowedserverlist)
{

  //removes all allowedservers in the list.  that means frees its allocated storage.

  GList *newallowedservers = NULL;
  GList *allowedservers = NULL;

  //free the old allowedservers list
  allowedservers = g_list_first (diradmin_group_get_objectclasses (conn));
  while (allowedservers)
    {
      g_free (allowedservers->data);
      allowedservers = g_list_next (allowedservers);
    }
  g_list_free (g_list_first (conn->diradmin_group_objectclasses));

  //make a copy of the passed allowedservers list into newallowedservers
  allowedservers = g_list_first (allowedserverlist);
  while (allowedservers)
    {
      newallowedservers =
	g_list_append (newallowedservers, g_strdup (allowedservers->data));
      allowedservers = g_list_next (allowedservers);
    }

  conn->diradmin_group_objectclasses = newallowedservers;
}








diradmin_group *
diradmin_group_new_from_ldap (connection_profile * usethisone, char *userdn)
{
  //conn should already be connected, or else undefined behaviour!!!

  diradmin_group *user = NULL;

  int ldap_errors;

  LDAPMessage *searchresults = NULL;
  LDAPMessage *entry = NULL;

  char **value_collection = NULL;

  gchar *filter;
  gchar *locale_attr;
  gchar *attribute;
  BerElement *attributehandler;

  int i = 0;


  user = g_new (diradmin_group, 1);
  user->diradmin_group_data = NULL;
  user->diradmin_group_members = NULL;
  user->diradmin_group_dnmembers = NULL;
  user->diradmin_group_objectclasses = NULL;


  //check 4 connection
  g_assert (connection_profile_get_ldap_handler (usethisone));

  filter = "objectclass=*";

  //look data up
  ldap_errors =
    ldap_search_s (connection_profile_get_ldap_handler (usethisone),
		   userdn, LDAP_SCOPE_BASE, filter, NULL, 0, &searchresults);
  if (ldap_errors)
    {

      //any error?
      g_print ("LDAP error while creating a diradmin_group structure for ");
      g_print (userdn);
      g_print (": ");
      g_print (ldap_err2string (ldap_errors));
      g_print ("\n");
      //ldap_msgfree (searchresults);
	  if (ldap_errors ==  LDAP_SERVER_DOWN) {
		connection_profile_invalidate(usethisone);
	  }
	  return NULL;
    }
  else
    {
      //get only first entry
      entry =
	ldap_first_entry (connection_profile_get_ldap_handler (usethisone),
			  searchresults);

      // loop thru attribute values

      diradmin_group_set_attribute (user, "dn", userdn);


      attribute =
	ldap_first_attribute (connection_profile_get_ldap_handler
			      (usethisone), entry, &attributehandler);

      g_assert (attribute);

      while (attribute)
	{
	  value_collection =
	    ldap_get_values (connection_profile_get_ldap_handler (usethisone),
			     entry, attribute);
	  //g_print ("%s = %s\n", attribute, value_collection[0]);
	  if (g_strcasecmp (attribute, "objectClass") == 0)
	    {
	      for (i = 0;value_collection[i];i++)
		{
		    //g_print ("    adding objectclass %s\n", value_collection[i]);
		    diradmin_group_add_objectclass (user, value_collection[i]);
		}
	    }
	  else if (g_strcasecmp (attribute, "memberUid") == 0)
	    {
	      for (i = 0;value_collection[i];i++)
                {
                  locale_attr = convert_from_utf8 (value_collection[i]);
			    //g_print ("    adding member%s\n", value_collection[i]);
                  user->diradmin_group_members =
                      g_list_append(user->diradmin_group_members,g_strdup(locale_attr));
                  g_free(locale_attr);
                }
	    }
	  else if (g_strcasecmp (attribute, "member") == 0)
	    {
	      for (i = 0;value_collection[i];i++)
                {
                  locale_attr = convert_from_utf8 (value_collection[i]);
			    //g_print ("    adding DN member%s\n", value_collection[i]);
		  diradmin_group_add_dnmember (user, locale_attr);
                  g_free(locale_attr);
                }
	    }
	  else
	    {
	      for (i = 0; value_collection[i]; i++)
		{
	     	  g_assert (value_collection[0]);
            	  locale_attr = convert_from_utf8 (value_collection[0]);
		  diradmin_group_set_attribute (user, attribute,locale_attr );
                  g_free(locale_attr);
		}
	    }
	  ldap_value_free (value_collection);
	  attribute =
	    ldap_next_attribute (connection_profile_get_ldap_handler
				 (usethisone), entry, attributehandler);
	}

      ldap_msgfree (searchresults);
    }

  return (user);
}

gchar *
gidnumber_to_cn (connection_profile * usethisone, gchar * gidnumber)
{
  //user is responsible to free the returned string

  LDAPMessage *results = NULL;
  LDAPMessage *entry = NULL;
  char **value_collection;
  int ldap_errors;
  gchar *filter;
  gchar *attributetoreturn[2];
  gchar *toreturn = NULL;

  if (connection_profile_is_connected (usethisone) == FALSE)
    {
      g_print
	("NOT CONNECTED!!!! - returning! (while finding out gidnumber_to_cn\n");
      return (NULL);
    }

  filter = g_strconcat ("(&(objectClass=posixGroup)(gidnumber=",
			gidnumber, "))", NULL);
  attributetoreturn[0] = "cn";
  attributetoreturn[1] = NULL;
//debug:  g_print(filter);
  //look data up
  ldap_errors =
    ldap_search_s (connection_profile_get_ldap_handler
		   (usethisone),
		   connection_profile_get_treeroot (usethisone),
		   LDAP_SCOPE_SUBTREE, filter, attributetoreturn,
		   0, &results);
  if (ldap_errors)
    {

      //any error?
      g_print ("LDAP error on gidnumber_to_cn: ");
      g_print (ldap_err2string (ldap_errors));
      g_print ("\n");
      toreturn = NULL;
    }
  else
    {
      g_assert (results);
      entry =
	ldap_first_entry (connection_profile_get_ldap_handler
			  (usethisone), results);
      if (entry == NULL)
	{

	  //any error?
	  g_print ("\n");
	  g_print
	    ("No posix groups available for translating gid to group name");
	  g_print ("\n");
	  toreturn = NULL;
	}
      else
	{

	  value_collection =
	    ldap_get_values (connection_profile_get_ldap_handler
			     (usethisone), entry, "cn");
	  g_assert (value_collection);
	  toreturn = g_strdup (value_collection[0]);
	  ldap_value_free (value_collection);
	}

      ldap_msgfree (results);
    }
  g_free (filter);
  return (toreturn);
}

gchar *
cn_to_gidnumber (connection_profile * usethisone, gchar * cn)
{
  //user is responsible to free the returned string

  LDAPMessage *results = NULL;
  LDAPMessage *entry = NULL;
  char **value_collection;
  int ldap_errors;
  gchar *filter;
  gchar *attributetoreturn[2];
  gchar *toreturn = NULL;
  gchar * utf8d_attr = NULL;

  utf8d_attr = convert_to_utf8(cn);

  if (connection_profile_is_connected (usethisone) == FALSE)
    {
      g_print
	("NOT CONNECTED!!!! - returning! (while finding out gidnumber_to_cn\n");
      return (NULL);
    }
  filter = g_strconcat ("(&(objectClass=posixGroup)(cn=", utf8d_attr, "))", 
NULL);
  attributetoreturn[0] = "gidnumber";
  attributetoreturn[1] = NULL;
  //g_print(filter);
  //look data up
  ldap_errors =
    ldap_search_s (connection_profile_get_ldap_handler
		   (usethisone),
		   connection_profile_get_treeroot
		   (usethisone), LDAP_SCOPE_SUBTREE,
		   filter, attributetoreturn, 0, &results);
  if (ldap_errors)
    {

      //any error?
      g_print ("LDAP error on cn_to_gidnumber: ");
      g_print (ldap_err2string (ldap_errors));
      g_print ("\n");
      toreturn = NULL;
    }
  else
    {
      g_assert (results);
      entry =
	ldap_first_entry (connection_profile_get_ldap_handler
			  (usethisone), results);
      if (entry == NULL)
	{

	  //any error?
	  g_print
	    ("No posix groups available for translating gid to group name: ");
	  g_print ("\n");
	  toreturn = NULL;
	}
      else
	{

	  value_collection =
	    ldap_get_values (connection_profile_get_ldap_handler
			     (usethisone), entry, "gidnumber");
	  g_assert (value_collection);
	  toreturn = g_strdup (value_collection[0]);
	  ldap_value_free (value_collection);
	}


      ldap_msgfree (results);
    }
  g_free (filter);
  g_free (utf8d_attr);
  return (toreturn);
}



ldaptransaction*
diradmin_group_generate_ldapdiff (diradmin_group *
				  oldone, diradmin_group * newone)
{

  ldaptransaction *t;
  gchar **values;
  gchar *attrs2chk[] = {
    "gidnumber","cn",NULL
  };
  GList *l = NULL;
  gint acnt;

  g_assert (oldone);
  g_assert (newone);
  t = ldaptransaction_new();

  for (acnt=0;attrs2chk[acnt];acnt++)
    {
      if (g_strcasecmp
	  (attrs2chk[acnt],
	   "groupPassword") != 0
	  && diradmin_group_get_attribute (newone,
					   attrs2chk
					   [acnt]) == NULL)
          ldaptransaction_delete(t,attrs2chk[acnt],NULL);
      else
	if (diradmin_group_get_attribute
	    (oldone,
	     attrs2chk[acnt]) == NULL
	    && diradmin_group_get_attribute (newone,
					     attrs2chk
					     [acnt]) != NULL)
	{
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8(
	     diradmin_group_get_attribute
		      (newone, attrs2chk[acnt]));
          ldaptransaction_replace(t, attrs2chk[acnt],values);
	}
      else
	if (strcmp
	    (diradmin_group_get_attribute
	     (oldone,
	      attrs2chk[acnt]),
	     diradmin_group_get_attribute (newone,
					   attrs2chk
					   [acnt])) != 0)
	{
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8(
	  /* g_strdup (*/diradmin_group_get_attribute
		      (newone, attrs2chk[acnt]));
          ldaptransaction_replace(t,attrs2chk[acnt],values);
	}
    }

  for (l = diradmin_group_get_objectclasses (oldone);l;l=g_list_next(l))
      if (diradmin_group_has_objectclass (newone, l->data) == FALSE)
	{
	  //generar mod de eliminacion
	  values = g_new0 (gchar *, 2);
	  values[0] = g_strdup (l->data);
          ldaptransaction_delete(t,"objectClass",values);
	}
  for (l = diradmin_group_get_objectclasses (newone);l;l=g_list_next(l))
      if (diradmin_group_has_objectclass (oldone, l->data) == FALSE)
	{
	  //generar mod de eliminacion
	  values = g_new0 (gchar *, 2);
	  values[0] = g_strdup (l->data);
          ldaptransaction_add(t,"objectClass",values);
	}
  for (l = diradmin_group_get_members (oldone);l;l=g_list_next(l))
      if (diradmin_group_has_member (newone, l->data) == FALSE)
	{
	  //generar mod de eliminacion
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8( l->data);
          ldaptransaction_delete(t,"memberUid",values);
	}
  for (l = diradmin_group_get_members (newone);l;l=g_list_next(l))
      if (diradmin_group_has_member (oldone, l->data) == FALSE)
	{
	  //generar mod de adicion
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8( l->data);
          ldaptransaction_add(t,"memberUid",values);
	}
  for (l = diradmin_group_get_dnmembers (oldone);l;l=g_list_next(l))
      if (diradmin_group_has_dnmember (newone, l->data) == FALSE)
	{
	  //generar mod de eliminacion
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8( l->data);
          ldaptransaction_delete(t,"member",values);
	}
  for (l = diradmin_group_get_dnmembers (newone);l;l=g_list_next(l))
      if (diradmin_group_has_dnmember (oldone, l->data) == FALSE)
	{
	  //generar mod de adicion
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8( l->data);
          ldaptransaction_add(t,"member",values);
	}


  return t;
}

diradmin_group *
create_group_struct_from_dialogbox (connection_profile
				    * conn, GtkWidget * dialogbox, gchar * dn)
{

  diradmin_group *newgroup;
  gint iterator;
  gchar *cn = NULL;
  gchar *gidnumber = NULL;
  GtkCList *members = NULL;
  gchar *member = NULL;
  gchar *membertype = NULL;
  gchar*membercn = NULL;
  GList *listone;
  dir_entry*memberentry;
  gint thisgidnumber;

	members = (GtkCList *) lookup_widget (dialogbox, "members");
	cn = gtk_entry_get_text (GTK_ENTRY (lookup_widget (dialogbox, "cn")));
	gidnumber =
		gtk_entry_get_text (GTK_ENTRY (lookup_widget (dialogbox, "gidnumber")));
	thisgidnumber = atoi(gidnumber);

  newgroup = diradmin_group_new (dn, cn, gidnumber);
  for (iterator = 0; iterator < members->rows; iterator++)
    {
		member = gtk_clist_get_row_data(members,iterator);
		gtk_clist_get_text (members, iterator, 0, &membertype);

		//handle case donde se cambia el primary group y despues recien se da click en add members
		memberentry = cached_dir_entries_getbydn(member);
		if (memberentry
			&& g_strcasecmp(membertype,"Primary") == 0
			&& memberentry->gidnumber != thisgidnumber)
		{
			g_print("      User %s is no longer primary, dropping\n",member);
		} else {
			g_print("      Appending to dnmembers %s member %s\n",membertype,member);
			diradmin_group_add_dnmember (newgroup, member);
		}
		//solo si el usuario existe todavia en la base de datos!
		if (memberentry && dir_entry_is_user(memberentry)) {
			if (g_strcasecmp(membertype,"Secondary") == 0) {
				membercn = dir_entry_get_uid(memberentry);
				g_print("      Appending to members %s member %s\n",membertype,membercn);
				diradmin_group_add_member(newgroup,membercn);
			}
		}
    }

  listone = diradmin_group_get_objectclasses (newgroup);
  while (listone)
    {
      g_print (listone->data);
      listone = listone->next;
    }

  return (newgroup);
}



ldaptransaction *
diradmin_group_create_ldapdiff (diradmin_group * newone)
{

  ldaptransaction * t;
  gchar *attrs2chk[] = {"cn", "gidnumber", NULL};
  GList *l = NULL;
  gint acnt = 0;
  dir_entry *userDN = NULL;
  gchar **values;

  g_assert (newone);
  t = ldaptransaction_new();

  values = g_new0 (gchar *, 7);
  values[0] = g_strdup ("top");
  values[1] = g_strdup ("posixGroup");
  if (g_list_length (diradmin_group_get_members (newone)))
    values[2] = g_strdup ("groupOfNames");
  ldaptransaction_add(t,"objectclass",values);

  for(acnt=0;attrs2chk[acnt];acnt++)
    {
      if (diradmin_group_get_attribute
	  (newone, attrs2chk[acnt]) != NULL)
	{
	  values = g_new0 (gchar *, 2);
	  values[0] = convert_to_utf8
		(diradmin_group_get_attribute(newone, attrs2chk[acnt]));
          ldaptransaction_add(t,attrs2chk[acnt],values);
	}
    }

  if (g_list_length (diradmin_group_get_members (newone)))
    {
    values = g_new0 (gchar *, 2 + g_list_length(diradmin_group_get_members (newone)));
    acnt = 0;
    for(l = diradmin_group_get_members (newone);l;l=g_list_next(l))
	{
	  values[acnt] =
	   convert_to_utf8( l->data);
          acnt++;
	}
    ldaptransaction_add(t,"memberUid",values);

    /* Generating DN list for groupOfNames */
    values = g_new0 (gchar *, 2 + g_list_length(diradmin_group_get_members (newone)));
    acnt = 0;
    for (l = diradmin_group_get_members (newone);l;l=g_list_next(l))
	{
          userDN = dir_entry_list_getbyuid (cached_dir_entries, l->data);
	  if (userDN) {
            g_print ("\n\n\n\n\n\n\n%s",dir_entry_get_dn(userDN));
	    values[acnt] = g_strdup(dir_entry_get_dn(userDN));
            acnt++;
	  }
	}
    ldaptransaction_add(t,"member",values);

    }


  return t;
}


syntax highlighted by Code2HTML, v. 0.9.1