/* 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 "appsupport.h"
#include "profile.h"
#include "users.h"
#include "groups.h"
#include "appglobals.h"
#include "appfunctions.h"
#include "modifydialogs.h"
#include "ldaptransaction.h"

void
fill_modifyuser (GtkWidget * modifyuserdialog, char *userdn)
{

GSList*accel ;
  connection_profile *usethisone = NULL;
  gchar *gidnumber = NULL;

  GList *attributes2fill = NULL;
  GList *loopix = NULL;
  char *row[2];
  char buf[2048];

  time_t the_time;

  diradmin_user *user = NULL;

  row[0] = NULL;
  row[1] = NULL;

  usethisone = current_connection_profile;

  user = diradmin_user_new_from_ldap (usethisone, userdn);
  if (user == NULL)  {
    gtk_widget_show(create_messagebox_with_message("The connection to the LDAP server has been lost."));
	gtk_widget_destroy(modifyuserdialog);
	return;
  }


  attributes2fill = g_list_append (attributes2fill, "dn");
  attributes2fill = g_list_append (attributes2fill, "uid");
  attributes2fill = g_list_append (attributes2fill, "givenname");
  attributes2fill = g_list_append (attributes2fill, "initials");
  attributes2fill = g_list_append (attributes2fill, "sn");
  attributes2fill = g_list_append (attributes2fill, "cn");
  attributes2fill = g_list_append (attributes2fill, "uidnumber");
  attributes2fill = g_list_append (attributes2fill, "homedirectory");
  attributes2fill = g_list_append (attributes2fill, "loginshell");
  attributes2fill = g_list_append (attributes2fill, "mail");
  attributes2fill = g_list_append (attributes2fill, "mailhost");
  attributes2fill = g_list_append (attributes2fill, "mailroutingaddress");
  attributes2fill = g_list_append (attributes2fill, "shadowmin");
  attributes2fill = g_list_append (attributes2fill, "shadowmax");
  attributes2fill = g_list_append (attributes2fill, "shadowwarning");
  attributes2fill = g_list_append (attributes2fill, "shadowinactive");
  attributes2fill = g_list_append (attributes2fill, "title");
  attributes2fill = g_list_append (attributes2fill, "ou");
  attributes2fill = g_list_append (attributes2fill, "smbHome");
  attributes2fill = g_list_append (attributes2fill, "homeDrive");
  attributes2fill = g_list_append (attributes2fill, "profilePath");
  attributes2fill = g_list_append (attributes2fill, "scriptPath");
  attributes2fill =
    g_list_append (attributes2fill, "physicaldeliveryofficename");
  attributes2fill = g_list_append (attributes2fill, "l");
  attributes2fill = g_list_append (attributes2fill, "o");
  attributes2fill = g_list_append (attributes2fill, "telephonenumber");
  attributes2fill =
    g_list_append (attributes2fill, "facsimiletelephonenumber");
  attributes2fill = g_list_append (attributes2fill, "homephone");
  attributes2fill = g_list_append (attributes2fill, "mobile");
  attributes2fill = g_list_append (attributes2fill, "employeenumber");
  loopix = g_list_first (attributes2fill);


  /* loop thru attribute values */
  while (loopix)
    {

      if (diradmin_user_get_attribute (user, loopix->data))
	gtk_entry_set_text (GTK_ENTRY
			    (lookup_widget (modifyuserdialog, loopix->data)),
			    g_strdup (diradmin_user_get_attribute
				      (user, loopix->data)));
      loopix = g_list_next (loopix);
    }

  /*the gidnumber requires special treatment due to its placement on
     a drop down box */

  fill_groups_dropdown (lookup_widget
			(modifyuserdialog, "gidnumberdropdown"));
  gidnumber =
    gidnumber_to_cn (usethisone,
		     diradmin_user_get_attribute (user, "gidnumber"));
  if (gidnumber)
    gtk_entry_set_text (GTK_ENTRY
			(lookup_widget (modifyuserdialog, "gidnumber")),
			gidnumber);

  gtk_combo_set_popdown_strings (GTK_COMBO (lookup_widget
					    (modifyuserdialog,
					     "loginshelldropdown")),
				 preferences.logindefaults.shells);
  //g_print ("\nSetting loginshell to %s\n",
	   //diradmin_user_get_attribute (user, "loginshell"));
  gtk_entry_set_text (GTK_ENTRY
		      (lookup_widget (modifyuserdialog, "loginshell")),
		      diradmin_user_get_attribute (user, "loginshell"));

  loopix = diradmin_user_get_allowedservers (user);
  while (loopix)
    {

      row[0] = loopix->data;
      g_print (row[0]);
      gtk_clist_append (GTK_CLIST
			(lookup_widget (modifyuserdialog, "allowedservers")),
			row);
      loopix = g_list_next (loopix);
    }
  if (diradmin_user_has_allservers (user))
    {
//      g_print("tenia todos los servers\n");
      gtk_toggle_button_set_active ((GtkToggleButton *)
				    lookup_widget (modifyuserdialog,
						   "logontoallservers"),
				    TRUE);
    }

  if (g_list_length(diradmin_user_get_allowedservers(user))>0)
    {
      //g_print("tiene algun server\n");
      gtk_toggle_button_set_active ((GtkToggleButton *)
				    lookup_widget (modifyuserdialog,
						   "logontoallservers"),
				    FALSE);
    }

  if (diradmin_user_has_objectclass (user, "sambaAccount"))
    gtk_toggle_button_set_active ((GtkToggleButton *)
				  lookup_widget (modifyuserdialog,
						 "enablesambaobjectclass"),
				  TRUE);
  if (diradmin_user_has_objectclass (user, "inetlocalmailrecipient"))
    {
      gtk_toggle_button_set_active ((GtkToggleButton *)
				    lookup_widget (modifyuserdialog,
						   "enablemailpolicycontrol"),
				    TRUE);
      if (diradmin_user_get_attribute (user, "mailhost") != NULL)
	gtk_toggle_button_set_active ((GtkToggleButton *)
				      lookup_widget (modifyuserdialog,
						     "mailhostset"), TRUE);
      if (diradmin_user_get_attribute (user, "mailroutingaddress") != NULL)
	gtk_toggle_button_set_active ((GtkToggleButton *)
				      lookup_widget (modifyuserdialog,
						     "mailroutingaddressset"),
				      TRUE);
    }
  if (diradmin_user_get_attribute (user, "shadowexpire") != NULL)
    {
      gtk_toggle_button_set_active ((GtkToggleButton *)
				    lookup_widget (modifyuserdialog,
						   "shadowexpirecheck"),
				    TRUE);
      the_time =
	(
	 atol
         (diradmin_user_get_attribute (user, "shadowexpire"))) *
            (60 * 60 * 24);
      gnome_date_edit_set_time ((GnomeDateEdit *)
				lookup_widget (modifyuserdialog,
					       "shadowexpire"), the_time);
    }

  snprintf (buf, sizeof buf, "User info for %s",
	    diradmin_user_get_attribute (user, "cn"));

  gtk_window_set_title (GTK_WINDOW (modifyuserdialog), (char *) &buf);

  diradmin_user_destroy (user);
  g_list_free (attributes2fill);


accel = gtk_accel_groups_from_object(GTK_OBJECT(modifyuserdialog));
gtk_accel_group_unref(accel->data);
gtk_window_remove_accel_group((GtkWindow*)modifyuserdialog,accel->data);


}


void
fill_modifygroup (GtkWidget * modifyuserdialog, char *userdn)
{

  connection_profile *usethisone = NULL;

  GList *attributes2fill = NULL;
  GList *loopix = NULL;
  char *row[3];
  char buf[2048];
  gint gidnumber;
  gint newrow;
  GtkCList* membersclist ;

  diradmin_group *user = NULL;
  GList *primarymembers = NULL;
  GList *secondarymembers = NULL;
  GList *dnmembers = NULL;
  dir_entry *memberdata = NULL;
  gchar*name;
  gchar*dn;

  row[0] = NULL;
  row[1] = NULL;
  row[2] = NULL;
  //row[3] = NULL;
  //row[4] = NULL;

  usethisone = current_connection_profile;

  user = diradmin_group_new_from_ldap (usethisone, userdn);
  if (user == NULL)  {
    gtk_widget_show(create_messagebox_with_message("The connection to the LDAP server has been lost."));
	gtk_widget_destroy(modifyuserdialog);
	return;
  }

membersclist =GTK_CLIST (lookup_widget (modifyuserdialog, "members"));


  attributes2fill = g_list_append (attributes2fill, "dn");
  attributes2fill = g_list_append (attributes2fill, "cn");
  attributes2fill = g_list_append (attributes2fill, "gidnumber");
  loopix = g_list_first (attributes2fill);

  /* loop thru attribute values */
  while (loopix)
    {

      gtk_entry_set_text (GTK_ENTRY
			  (lookup_widget (modifyuserdialog, loopix->data)),
			  g_strdup (diradmin_group_get_attribute
				    (user, loopix->data)));
      loopix = g_list_next (loopix);
    }

/*
  loopix = diradmin_group_get_members (user);
  while (loopix)
    {

      row[0] = loopix->data;
      gtk_clist_append (GTK_CLIST
			(lookup_widget (modifyuserdialog, "members")), row);
      loopix = g_list_next (loopix);
    }
*/

  // bring primary members to the salad.
  gidnumber=atoi ( diradmin_group_get_attribute (user, "gidnumber" ) );

	for (loopix=g_list_first(cached_dir_entries);loopix != NULL;loopix=loopix->next) {
	g_assert(loopix->data);
	memberdata = loopix->data;
	if (dir_entry_is_user(memberdata)) {
		dn = g_strdup(dir_entry_get_dn(memberdata));
		//g_print("  GID number: %d\n",dir_entry_get_gidnumber(memberdata));
		//si es el mismo gid number entonces unamos su DN a la lista
		if (dir_entry_get_gidnumber(memberdata) ==gidnumber )
			primarymembers = g_list_append(primarymembers,dn);
		}
	}

  // bring secondary members to the salad.

  for (loopix=diradmin_group_get_members (user);loopix != NULL;loopix=loopix->next)
    {
		g_assert(loopix->data);
		g_print("    Trying to get the cached directory entry of %s\n",(char*)loopix->data);
		memberdata = cached_dir_entries_getbyuid(loopix->data);
		if (memberdata) {
			dn = g_strdup(dir_entry_get_dn(memberdata));
			//unamos cada uno de sus DNs a la lista de secundarios
			if (g_list_find_custom  (primarymembers, dn, (GCompareFunc) g_strcasecmp) == NULL)
				secondarymembers = g_list_append(secondarymembers,dn);
		}
    }

  // bring DN members to the salad.
  // esto esta TOSTADO
	for (loopix= diradmin_group_get_dnmembers (user);loopix != NULL;loopix=loopix->next)
	{
		//falta revisar si alguno de estos elementos ya existen, no añadirse a la lista?
		g_assert(loopix->data);
		dn = g_strdup(loopix->data);
		if (g_list_find_custom  (primarymembers, loopix->data, (GCompareFunc) g_strcasecmp) == NULL)
			if (g_list_find_custom  (secondarymembers, loopix->data, (GCompareFunc) g_strcasecmp) == NULL)
				dnmembers = g_list_append(dnmembers,dn);
	}

//fill the gtk c list


  loopix = primarymembers;
  while (loopix)
    {
		g_assert(loopix->data);
		dn=(loopix->data);
		name = (gchar*)cached_dir_entries_getbydn(dn);
		g_assert(name);
		name = dir_entry_get_name((dir_entry*)name);
		name = g_strconcat(name," (",dn,")",NULL);
		row[0] = g_strdup("Primary");
		row[1] = name;
		newrow = gtk_clist_append (membersclist, row);
		//g_print("Appending primary member %s to list, with DN in %d\n",name,dn);
		gtk_clist_set_row_data(membersclist,newrow,dn);
		loopix = g_list_next (loopix);
    }
loopix = secondarymembers;
  while (loopix)
    {
		dn=loopix->data;
		name = (gchar*)cached_dir_entries_getbydn(dn);
		g_assert(name);
		name = dir_entry_get_name((dir_entry*)name);
		name = g_strconcat(name," (",dn,")",NULL);
		row[0] = g_strdup("Secondary");
		row[1] = name;
		newrow = gtk_clist_append (membersclist, row);
		//g_print("Appending secondary member %s to list, with DN in %d\n",name,dn);
		gtk_clist_set_row_data(membersclist,newrow,dn);
		loopix = g_list_next (loopix);
    }
loopix = dnmembers;
  while (loopix)
    {
		dn=loopix->data;
		name = g_strdup(dn);
		row[0] = g_strdup("LDAP");
		row[1] = name;
		newrow = gtk_clist_append (membersclist, row);
		//g_print("Appending DN member %s to list, with DN in %d\n",name,dn);
		gtk_clist_set_row_data(membersclist,newrow,dn);
		loopix = g_list_next (loopix);
    }

gtk_clist_columns_autosize(membersclist);
//gtk_clist_set_compare_func(membersclist,(GtkCListCompareFunc)g_strcasecmp);
g_print("Setting auto sort on members list\n");
gtk_clist_set_sort_column(membersclist,1);
gtk_clist_set_auto_sort(membersclist,TRUE);
gtk_clist_sort(membersclist);


//free up the lists
g_list_free(dnmembers);
g_list_free(secondarymembers);
g_list_free(primarymembers);


  snprintf (buf, sizeof buf, "Group info for %s",
	    diradmin_group_get_attribute (user, "cn"));

  gtk_window_set_title (GTK_WINDOW (modifyuserdialog), (char *) &buf);

/*  g_list_free(primarymembers);
  g_list_free(secondarymembers);
  g_list_free(dnmembers);*/

  diradmin_group_destroy (user);

  g_list_free (attributes2fill);

}

gboolean
modifyuser_check (GtkWidget * window)
{
  gboolean changingpassword;
  gchar *userpassword = NULL;
  gchar *userpasswordconfirm = NULL;
  dir_entry*found;



if (preferences.avoidconflicts && preferences.avoidconflictscope == ENTIREDIR) {
found = cached_dir_entries_getbyuid( gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "uid")) ) );
if (found && g_strcasecmp(found->dn,gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "dn")))) != 0) {
	{
      gtk_widget_show (create_messagebox_with_message
		       ("The user ID you typed already exists in the directory.  Please choose another."));
      return (ERROR);
    }
}
}


  changingpassword =
    GTK_WIDGET_VISIBLE (lookup_widget (GTK_WIDGET (window), "tablepassword"));
  userpassword =
    gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "userpassword")));
  userpasswordconfirm =
    gtk_entry_get_text (GTK_ENTRY
			(lookup_widget (window, "userpasswordconfirm")));
  if (gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "uid"))) == NULL)
    {
      gtk_widget_show (create_messagebox_with_message
		       ("You need to supply a user ID"));
      return ERROR;
    }
  if (gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "uidnumber"))) ==
      NULL)
    {
      gtk_widget_show (create_messagebox_with_message
		       ("You need to supply a UNIX UID number"));
      return ERROR;
    }
  if (changingpassword)
    {
      if (strlen (userpassword) == 0 && strlen (userpasswordconfirm) == 0)
	{
	  gtk_widget_show (create_messagebox_with_message
			   ("You need to supply a password"));
	  return ERROR;
	}
      if (userpassword
	  &&
	  userpasswordconfirm
	  && strcmp (userpassword, userpasswordconfirm) != 0)
	{
	  gtk_widget_show (create_messagebox_with_message
			("The passwords you entered do not match.  Please check them."));
	  return ERROR;
	}
      if (userpassword
	  &&
	  userpasswordconfirm
	  && strlen (userpassword) < preferences.logindefaults.PASS_MIN_LEN)
	{
	  gtk_widget_show (create_messagebox_with_message
			 ("The password is too short"));
	  return ERROR;
	}
    }

  return OK;

}




gboolean
modifyuser_commit (GtkWidget * window)
{


  diradmin_user *olduser = NULL;
  diradmin_user *newuser = NULL;
//  diradmin_user *oldgroup = NULL;
//  diradmin_user *newgroup = NULL;
  int ldap_errors = LDAP_SUCCESS;
  ldaptransaction * t = NULL;
  gchar *dn = NULL;
  char buf[2048];
int              uidnumber_holder = 0;
int              gidnumber_holder = 0;
  dir_entry*d_entry;
  char*oldgroupdn = NULL;dir_entry*oldgroupentry = NULL;
char*newgroupdn = NULL;dir_entry*newgroupentry = NULL;
int oldgidnumber; char*oldgidnumberstring;
int newgidnumber; char*newgidnumberstring;
char*uid;
gint changesocurred = 0;
dir_entry*found;
gchar* old_uid,*new_uid;
gchar*filter;  LDAP *conn = NULL;
  gchar *root = NULL;  LDAPMessage *results = NULL;
  LDAPMessage *entry = NULL; gchar *attributetoreturn[8];



  if (connection_profile_is_connected (current_connection_profile) == FALSE)
    return ERROR;
  dn = gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "dn")));

  newuser = create_user_struct_from_dialogbox (current_connection_profile,
					       window, dn);

  olduser = diradmin_user_new_from_ldap (current_connection_profile, dn);




//get old and new gid numbers for group update later
oldgidnumberstring = diradmin_user_get_attribute(olduser,"gidnumber");
g_assert(oldgidnumberstring);
oldgidnumber = atoi (oldgidnumberstring);

newgidnumberstring = diradmin_user_get_attribute(newuser,"gidnumber");
g_assert(newgidnumberstring);
newgidnumber = atoi (newgidnumberstring);

/*  diradmin_user_dump (olduser);
  diradmin_user_dump (newuser);*/


  t = diradmin_user_generate_ldapdiff (olduser, newuser);
  if (ldaptransaction_has_mods(t))
    {
	changesocurred = 1;
	g_print("\nEntry was modified.  Changes follow:\n");
	ldaptransaction_dump(t);
	  ldap_errors =
	connection_profile_commit_modifications (current_connection_profile,
						 t->mods, dn);
      if (ldap_errors)
	{
	  if (ldap_errors == LDAP_OBJECT_CLASS_VIOLATION)
	    g_snprintf (buf, 2048,
			"A required field is empty, has invalid characters, or your directory does not\nsupport a required object class. Please complete missing fields, correct invalid\ncharacters and check if your directory has support for needed object classes.");
	  else if (ldap_errors == LDAP_NO_SUCH_OBJECT)
	    g_snprintf (buf, 2048,
			"Your directory seems to be empty.  Directory administrator requires a directory\nwith at least one group and one organizational unit. Visit PADL.com and look for\nthe MigrationTools which will help you populate your directory server.");
	  else if (ldap_errors == LDAP_INVALID_SYNTAX)
	    g_snprintf (buf, 2048,
			"You specified invalid characters in one of the entry boxes (such as letters\nwhere only numbers are accepted).  Please go back and correct errors.");
	  else if (ldap_errors == LDAP_UNDEFINED_TYPE)
	    g_snprintf (buf, 2048,
"Your directory server appears not to support a required object class.  Please tweak\ncompatibility options in Settings->Preferences or disable object class checking.");
	  else
	    g_snprintf (buf, 2048, "Error: %s",
			ldap_err2string (ldap_errors));
	  gtk_widget_show (create_messagebox_with_message (buf));
	}

    }
  ldaptransaction_destroy(t);
  if (ldap_errors) {
    diradmin_user_destroy (olduser);
    diradmin_user_destroy (newuser);
    return ERROR;
  }

    uidnumber_holder =
       atoi(diradmin_user_get_attribute(newuser,"uidnumber"));
    gidnumber_holder =
       atoi(diradmin_user_get_attribute(newuser,"gidnumber"));
              d_entry =
                dir_entry_user_new (
g_strdup(diradmin_user_get_attribute(olduser,"dn")),
                g_strdup(diradmin_user_get_attribute(newuser,"uid")),
                g_strdup(diradmin_user_get_attribute(newuser,"gecos")),
                    uidnumber_holder, gidnumber_holder);


	oldgroupentry = cached_dir_entries_getgroupbygidnumber(oldgidnumber);
	newgroupentry = cached_dir_entries_getgroupbygidnumber(newgidnumber);
	if (oldgroupentry) oldgroupdn = dir_entry_get_dn(oldgroupentry);
	if (newgroupentry) newgroupdn = dir_entry_get_dn(newgroupentry);
	if (oldgroupdn && newgroupdn && oldgidnumber != newgidnumber)
	{
		g_print("\n\nDirectory administrator detected that the group changed from %d to %d\n",
			oldgidnumber,newgidnumber);
		//ahora sacamos el DN de este usuario de su viejo grupo primario
		uid = diradmin_user_get_attribute(newuser,"uid");
		_delete_this_user_from_this_group(oldgidnumber,dn,uid); //borra el uid y el DN
		//ahora ponemos el DN de este usuario en su nuevo grupo primario
		//esto arregla el problema de que el usuario era antes secondary member del grupo
		_delete_this_uid_from_this_group(uid,newgidnumber);
		_add_this_dn_to_this_group(dn,newgidnumber);
		g_print("gid number: %d",newgidnumber);

	}

if (changesocurred) {
  app_delete_dir_entry(diradmin_user_get_attribute(olduser,"dn"));
  app_add_dir_entry(d_entry);
}


// now it's time to rename the user from every group he's secondary member of

old_uid = diradmin_user_get_attribute(olduser,"uid");
new_uid = diradmin_user_get_attribute(newuser,"uid");
if (old_uid && new_uid && strcmp(old_uid,new_uid) != 0) {
  g_print("Directory administrator detected an UID change: updating all groups with new membership info\n");
  attributetoreturn[0] = "1.1";
  attributetoreturn[1] = NULL;

  filter = g_strconcat ("(&(member=",dn,")(objectclass=groupOfNames)(!(gidnumber=",
  diradmin_user_get_attribute(newuser,
  "gidnumber"),")))",NULL);
g_print("Searching with filter: %s\n",filter);
  conn = connection_profile_get_ldap_handler (current_connection_profile);
  root = connection_profile_get_treeroot (current_connection_profile);

  //look data up
  ldap_errors =
    ldap_search_s (conn, root, LDAP_SCOPE_SUBTREE, filter,
		   attributetoreturn, 0, &results);
		   g_free(filter);
  if (ldap_errors)
    {
      g_print ("LDAP error while searching for groups the user was member of: %s\n",
	       ldap_err2string (ldap_errors));
       diradmin_user_destroy (olduser);
       diradmin_user_destroy (newuser);
       ldap_msgfree (results);
       return ERROR;
    }
  g_assert (results);

  for (entry=ldap_first_entry(conn,results);entry;entry=ldap_next_entry(conn, entry)) {
	//for each matching group
		g_print("          updating group %s\n",ldap_get_dn(conn,entry));
		_group_switch_memberuids(ldap_get_dn(conn,entry),old_uid,new_uid);
		//_group_add_memberuid(ldap_get_dn(conn,entry),new_uid);
  }

  ldap_msgfree (results);


}


  diradmin_user_destroy (olduser);
  diradmin_user_destroy (newuser);


  return OK;
}


gboolean
modifygroup_check (GtkWidget * window)
{

dir_entry*found;

if (preferences.avoidconflicts && preferences.avoidconflictscope == ENTIREDIR) {
found = cached_dir_entries_getgroupbycn( gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "cn")) ) );
if (found && g_strcasecmp(found->dn,gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "dn")))) != 0) {
	{
      gtk_widget_show (create_messagebox_with_message
		       ("The group name you typed already exists in the directory.  Please choose another."));
      return (ERROR);
    }
}
}



  if (gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "cn"))) == NULL)
    {
      gtk_widget_show
	(create_messagebox_with_message ("You need to supply a group name"));
      return ERROR;
    }
  if (gtk_entry_get_text
      (GTK_ENTRY (lookup_widget (window, "gidnumber"))) == NULL)
    {
      gtk_widget_show
	(create_messagebox_with_message
	 ("You need to supply a UNIX GID number"));
      return ERROR;
    }
  return OK;
}

gboolean
modifygroup_commit (GtkWidget * window)
{
  ldaptransaction *t;
  diradmin_group *olduser = NULL;
  diradmin_group *newuser = NULL;
  int ldap_errors = LDAP_SUCCESS;
  gchar *dn;
  char buf[2048];
  dir_entry*d_entry;
  int gidnumber_holder;
int changesocurred = 0;

  if (connection_profile_is_connected (current_connection_profile) == FALSE)
    return ERROR;
  dn = gtk_entry_get_text (GTK_ENTRY (lookup_widget (window, "dn")));
  newuser =
    create_group_struct_from_dialogbox
    (current_connection_profile, window, dn);
  olduser = diradmin_group_new_from_ldap (current_connection_profile, dn);
  t = diradmin_group_generate_ldapdiff (olduser, newuser);
  if (ldaptransaction_has_mods(t))
    {
	 changesocurred = 1;
	g_print("\nEntry was modified.  Changes follow:\n");
	ldaptransaction_dump(t);

	  ldap_errors =
	connection_profile_commit_modifications
	(current_connection_profile, t->mods, dn);
      if (ldap_errors)
	{
	  if (ldap_errors == LDAP_OBJECT_CLASS_VIOLATION)
	    g_snprintf (buf, 2048,
			"A required field is empty, has invalid characters, or your directory does not\nsupport a required object class. Please complete missing fields, correct invalid\ncharacters and check if your directory has support for needed object classes.");
	  else if (ldap_errors == LDAP_NO_SUCH_OBJECT)
	    g_snprintf (buf, 2048,
			"Your directory seems to be empty.  Directory administrator requires a directory\nwith at least one group and one organizational unit. Visit PADL.com and look for\nthe MigrationTools which will help you populate your directory server.");
	  else if (ldap_errors == LDAP_INVALID_SYNTAX)
	    g_snprintf (buf, 2048,
			"You specified invalid characters in one of the entry boxes (such as letters\nwhere only numbers are accepted).  Please go back and correct errors.");
	  else if (ldap_errors == LDAP_UNDEFINED_TYPE)
	    g_snprintf (buf, 2048,
			"Your directory server appears not to support a required object class.  Please tweak\ncompatibility options in Settings->Preferences or disable object class checking.");
	  else
	    g_snprintf (buf, 2048, "Error: %s",
			ldap_err2string (ldap_errors));
	  gtk_widget_show (create_messagebox_with_message (buf));
	}
    }
  ldaptransaction_destroy(t);
  if (ldap_errors) {
    diradmin_group_destroy (olduser);
    diradmin_group_destroy (newuser);
    return ERROR;
}

               //si no hay common name, al menos use gecos
    gidnumber_holder =
       atoi(diradmin_group_get_attribute(newuser,"gidnumber"));
              d_entry =
                dir_entry_group_new (
        g_strdup(diradmin_group_get_attribute(olduser,"dn")),
        g_strdup(diradmin_group_get_attribute(newuser,"cn")),
                     gidnumber_holder);

  if (changesocurred) {
app_delete_dir_entry(diradmin_group_get_attribute(olduser,"dn"));
  app_add_dir_entry(d_entry);
}
//  g_print("\nThe following entry was just added to the directory cache");
//  dir_entry_dump(d_entry);

  diradmin_group_destroy (olduser);
  diradmin_group_destroy (newuser);


  return OK;
}


void modifyuser_exec_accel(GtkWidget* window,GdkEventKey     *event) {

// this entire function is dedicated to the fuckup GNOME/GTK+ causes with accelerators
/*g_print("Disabled actions\n");
return;*/
	//ALT accelerators
	if (event->state & 8) {

		if (strcasecmp(event->string,"p") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),0);
			event->string = g_strdup("f");
		}
		if (strcasecmp(event->string,"o") == 0) {
			gtk_notebook_set_page ((GtkNotebook*) lookup_widget(window,"propertypages"),1);
			event->string = g_strdup("c");
		}
		if (strcasecmp(event->string,"u") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),2);
			// event->string = g_strdup("f"); no need to, already first letter
		}
		if (strcasecmp(event->string,"w") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),3);
			// event->string = g_strdup("f");
		}
		if (strcasecmp(event->string,"s") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),4);
			event->string = g_strdup("f");
		}
		if (strcasecmp(event->string,"e") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),5);
			//event->string = g_strdup("f");
		}
		if (strcasecmp(event->string,"a") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),6);
			//event->string = g_strdup("f");
		}




	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 0) {
		g_print("Selecting widgets from Personal tab\n");
		if (strcasecmp(event->string,"f") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"givenname"));
		if (strcasecmp(event->string,"m") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"initials"));
		if (strcasecmp(event->string,"l") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"sn"));;
		if (strcasecmp(event->string,"h") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"cn"));
		if (strcasecmp(event->string,"g") == 0)
			gtk_button_clicked(GTK_BUTTON(lookup_widget(window,"button_passwd")));
		if (strcasecmp(event->string,"w") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"userpassword"));
		if (strcasecmp(event->string,"r") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"userpasswordconfirm"));


//						gtk_widget_grab_focus (lookup_widget(window,"cn"));

	}
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 1) {
		g_print("Selecting widgets from Organization tab\n");
		if (strcasecmp(event->string,"c") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"o")));
		if (strcasecmp(event->string,"j") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"title")));
		if (strcasecmp(event->string,"n") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"physicaldeliveryofficename")));
		if (strcasecmp(event->string,"d") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"ou")));
		if (strcasecmp(event->string,"y") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"l")));
		if (strcasecmp(event->string,"m") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"employeenumber")));
		if (strcasecmp(event->string,"k") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"telephonenumber")));
		if (strcasecmp(event->string,"f") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"facsimiletelephonenumber")));
		if (strcasecmp(event->string,"h") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"homephone")));
		if (strcasecmp(event->string,"b") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"mobile")));
	}

	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 2) {
		g_print("Selecting widgets from User account tab\n");
		if (strcasecmp(event->string,"u") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"uid")));
		if (strcasecmp(event->string,"m") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"gidnumber")));
		if (strcasecmp(event->string,"n") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"uidnumber")));
		if (strcasecmp(event->string,"h") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"homedirectory")));
		if (strcasecmp(event->string,"l") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"loginshell")));
	}

	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 3) {
		g_print("Selecting widgets from Windows domain tab\n");
		if (strcasecmp(event->string,"w") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"enablesambaobjectclass")));
		if (strcasecmp(event->string,"h") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"smbHome")));
		if (strcasecmp(event->string,"d") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"homeDrive")));
		if (strcasecmp(event->string,"t") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"profilePath")));
		if (strcasecmp(event->string,"l") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"scriptPath")));
	}
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 4) {
		g_print("Selecting widgets from Security tab\n");
		if (strcasecmp(event->string,"f") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"shadowmin")));
		if (strcasecmp(event->string,"c") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"shadowmax")));
		if (strcasecmp(event->string,"n") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"shadowwarning")));
		if (strcasecmp(event->string,"d") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"shadowinactive")));
		if (strcasecmp(event->string,"x") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"shadowexpirecheck")));
	}

	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 5) {
		g_print("Selecting widgets from Mail tab\n");
		if (strcasecmp(event->string,"e") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"mail")));
		if (strcasecmp(event->string,"d") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"enablemailpolicycontrol")));
		if (strcasecmp(event->string,"v") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"mailroutingaddressset")));
		if (strcasecmp(event->string,"r") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"mailhostset")));
	}
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 6) {
		g_print("Selecting widgets from Access control tab\n");
		if (strcasecmp(event->string,"a") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"logontoallservers")));
		if (strcasecmp(event->string,"h") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"selectedserver")));
		if (strcasecmp(event->string,"n") == 0)
			gtk_widget_grab_focus(GTK_WIDGET(lookup_widget(window,"allowedservers")));
		if (strcasecmp(event->string,"d") == 0)
			gtk_button_clicked (GTK_BUTTON(lookup_widget(window,"addserver")));
		if (strcasecmp(event->string,"r") == 0)
			gtk_button_clicked (GTK_BUTTON(lookup_widget(window,"delserver")));
	}


	}


	//CTRL accelerators
	if (event->state & 4) {
		if (event->keyval == 65366) {
			gtk_notebook_next_page ((GtkNotebook*)lookup_widget(window,"propertypages"));
		}

		if (event->keyval == 65365) {
			gtk_notebook_prev_page ((GtkNotebook*)lookup_widget(window,"propertypages"));
		}
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"givenname")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 1)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"o")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 2)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"uid")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 3)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"enablesambaobjectclass")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 4)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"shadowmin")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 5)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"mail")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 6)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"logontoallservers")));



	}

//other accelerators

		if (event->keyval == 65293 || event->keyval == 65421) {
			if (
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"button_passwd")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"gidnumber")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"gidnumberdropdown")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"loginshell")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"loginshelldropdown")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"enablesambaobjectclass")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"shadowexpirecheck")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"shadowexpire")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"enablemailpolicycontrol")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"mailroutingaddressset")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"mailhostset")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"logontoallservers")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"addserver")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"delserver")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"allowedservers"))

			)
			gtk_button_clicked((GtkButton*)lookup_widget(window,"modifyuser_okay"));
		}

}

void modifyuser_keypress(GtkWidget* window,GdkEventKey     *event)
{


//  guint32 delta;
//  gchar*tmp;

//  GtkWidget * delbutton;
  unsigned char letter;
  int key;

  letter=event->string[0];
  key = event->keyval;

  g_print("Keypress on modify user dialog %d (%s) state %d\n",event->keyval,event->string,event->state);


  if (event->state & 8)
		g_print("(Alt was pressed)\n");
  if (event->state & 4)
		g_print("(Control was pressed)\n");

	modifyuser_exec_accel(window,event);


return;




}






void modifygroup_exec_accel(GtkWidget* window,GdkEventKey     *event) {

// this entire function is dedicated to the fuckup GNOME/GTK+ causes with accelerators
/*g_print("Disabled actions\n");
return;*/
	//ALT accelerators
	if (event->state & 8) {

		if (strcasecmp(event->string,"g") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),1);
			event->string = g_strdup("n");
		}
		if (strcasecmp(event->string,"m") == 0) {
			gtk_notebook_set_page ( (GtkNotebook*)lookup_widget(window,"propertypages"),0);
			event->string = g_strdup("m");
		}


	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 1) {
		g_print("Selecting widgets from Group information tab\n");
		if (strcasecmp(event->string,"n") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"cn"));
		if (strcasecmp(event->string,"i") == 0)
			gtk_widget_grab_focus (lookup_widget(window,"gidnumber"));

	}
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 0) {
		g_print("Selecting widgets from Memberships tab\n");
		if (strcasecmp(event->string,"m") == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"members")));
	}


	}


	//CTRL accelerators
	if (event->state & 4) {
		if (event->keyval == 65366)
			gtk_notebook_next_page ((GtkNotebook*)lookup_widget(window,"propertypages"));

		if (event->keyval == 65365)
			gtk_notebook_prev_page ((GtkNotebook*)lookup_widget(window,"propertypages"));

	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 0)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"members")));
	if (gtk_notebook_get_current_page((GtkNotebook*)lookup_widget(window,"propertypages")) == 1)
			gtk_widget_grab_focus (GTK_WIDGET(lookup_widget(window,"cn")));


	}

//other accelerators
		if (event->keyval == 65293 || event->keyval == 65421) {

			if (
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"add_members")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"delete_selected")) &&
			   !GTK_WIDGET_HAS_FOCUS(lookup_widget(window,"members"))

			)
{
			gtk_button_clicked((GtkButton*)lookup_widget(window,"modifygroup_okay"));
			}

		}

}

void modifygroup_keypress(GtkWidget* window,GdkEventKey     *event)
{


/*  guint32 delta;
  gchar*tmp;

  GtkWidget * delbutton;*/
  unsigned char letter;
  int key;

  letter=event->string[0];
  key = event->keyval;

  g_print("Keypress on modify group dialog %d (%s) state %d\n",event->keyval,event->string,event->state);


  if (event->state & 8)
		g_print("(Alt was pressed)\n");
  if (event->state & 4)
		g_print("(Control was pressed)\n");

	modifygroup_exec_accel(window,event);


return;




}





syntax highlighted by Code2HTML, v. 0.9.1