/* PureAdmin * Copyright (C) 2003 Isak Savo * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * Usermanager functions * * Copyright (C) 2003 Isak Savo */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "cfg.h" #include "gui_helper.h" #include "globals.h" #include "helper.h" #include "system_accounts.h" #include "usr_manager.h" #include "purepw.h" GladeXML *usrm_xml = NULL; typedef struct { GdkPixbuf *icon; gchar *login; gchar *realname; } PGuiUsermanRow; static GtkWidget *create_usermanager (void) { gchar *our_path; our_path = g_build_filename (datadir, PACKAGE, "usermanager.glade", NULL); usrm_xml = glade_xml_new (our_path, NULL, NULL); g_free (our_path); glade_xml_signal_autoconnect (usrm_xml); return UW("usermanager"); } static void free_usredit_struct (GtkWidget *dlg, gpointer data) { struct usrman_info_widgets **w = (struct usrman_info_widgets **) data; g_free (*w); *w = NULL; } static void free_pwstruct (PWInfo *i) { if (!i) return; g_free (i->login); g_free (i->pwd); g_free (i->home); g_free (i->gecos); g_free (i->allow_local_ip); g_free (i->deny_local_ip); g_free (i->allow_client_ip); g_free (i->deny_client_ip); g_free (i); } static struct usrman_info_widgets *get_widgets (void) { static struct usrman_info_widgets *ret = NULL; if (G_UNLIKELY (!ret)) { ret = g_new0 (struct usrman_info_widgets, 1); ret->login = UW("entry_username"); ret->realname = UW("entry_realname"); ret->e_uid = UW("optmenu_uid"); ret->e_gid = UW("optmenu_gid"); ret->chk_chroot = UW("chk_chroot"); ret->home = UW("entry_home"); ret->root = UW("entry_fakeroot"); ret->quota_files = UW("spin_maxfiles"); ret->quota_size = UW("spin_maxsize"); ret->timelimit = UW("entry_timerestrictions"); ret->simsess = UW("spin_simsessions"); ret->loc_allow = UW("entry_allowedlocalip"); ret->loc_deny = UW("entry_deniedlocalip"); ret->cli_allow = UW("entry_allowedclientip"); ret->cli_deny = UW("entry_deniedclientip"); ret->bw_ul = UW("spin_ulbwidth"); ret->bw_dl = UW("spin_dlbwidth"); ret->ul_ratio = UW("spin_ratioup"); ret->dl_ratio = UW("spin_ratiodown"); ret->btn_pwchange = UW("btn_change_pw"); ret->btn_savechanges = UW("btn_save_changes"); ret->btn_cancelchanges = UW("btn_cancel_changes"); ret->lbl_invalid_uid = UW("lbl_invalid_uid"); ret->lbl_invalid_gid = UW("lbl_invalid_gid"); ret->btn_browse_homedir = UW("btn_browse_homedir"); ret->btn_browse_fakeroot = UW("btn_browse_fakeroot"); g_signal_connect (G_OBJECT (UW("usermanager")), "destroy", G_CALLBACK (free_usredit_struct), &ret); } return ret; } /* Returns all information stored in the user information widgets */ static PWInfo *usr_widgets_get_info (void) { PWInfo *i; struct usrman_info_widgets *w; gchar *tmp, *t_home, *t_root; GList *items; gint sel; i = g_new0 (PWInfo, 1); w = get_widgets (); if (G_UNLIKELY (i == NULL || w == NULL)) return NULL; i->login = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->login))); i->gecos = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->realname))); i->pwd = g_strdup ((gchar *) g_object_get_data (G_OBJECT (w->btn_pwchange), "usr_password")); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w->chk_chroot))) { /* Chroot user */ i->chroot = TRUE; t_home = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->home))); t_root = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->root))); /* FIXME: Verify that this works for UTF-8 strings */ tmp = t_home + strlen (t_home) - 1; while (*tmp == '/') { *tmp = 0; tmp--; } tmp = t_root + strlen (t_root) - 1; while (*tmp == '/') { *tmp = 0; tmp--; } if (strlen (t_root) > strlen (t_home) || strncmp (t_home, t_root, strlen (t_root)) != 0) { pur_log_nfo ("Fake root error: %s not part of %s", t_root, t_home); i->home = g_strdup_printf ("%s/./", t_home); gtk_entry_set_text (GTK_ENTRY (w->root), t_home); /* The fake root that the user specified wasn't part of the home directory and thus invalid! */ gui_display_msgdialog (_("Invalid fake root"), _("The fake root you've selected is not a part of the homedirectory. The value has been defaulted to the users homedirectory."), MSGDLG_TYPE_WARNING, UW("usermanager")); } else if (strcmp (t_home, t_root) == 0) i->home = g_strdup_printf ("%s/./", t_home); else { tmp = t_home + strlen (t_root); *tmp = 0; tmp++; /* points to the remaining part of the home-dir */ i->home = g_strdup_printf ("%s/./%s", t_root, tmp); } g_free (t_home); g_free (t_root); } else { i->chroot = FALSE; i->home = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->home))); tmp = i->home + strlen (i->home) - 1; while (*tmp == '/') { *tmp = 0; tmp--; } } if (!g_path_is_absolute (i->home)) { /* Home directory *MUST* be an absolute path, starting with a '/' */ pur_log_wrn ("Invalid homedir: %s is not absolute!", i->home); gui_display_msgdialog (_("Invalid home directory"), _("The home directory you have specified is not an absolute path (i.e. not starting with a '/'). Information could not be saved"), MSGDLG_TYPE_ERROR, UW("usermanager")); free_pwstruct (i); return NULL; } /* UID / GID -- Needs conversion from menuitems to int */ SystemAccount *tmp_account; sel = gtk_option_menu_get_history (GTK_OPTION_MENU (w->e_uid)); items = g_object_get_data (G_OBJECT (w->e_uid), "items"); tmp_account = (SystemAccount*) g_list_nth (items, sel)->data; if (tmp_account) i->uid = tmp_account->id; sel = gtk_option_menu_get_history (GTK_OPTION_MENU (w->e_gid)); items = g_object_get_data (G_OBJECT (w->e_gid), "items"); tmp_account = (SystemAccount*) g_list_nth (items, sel)->data; if (tmp_account) i->gid = tmp_account->id; /* Time -- Needs conversion from char to ints */ tmp = (gchar *) gtk_entry_get_text (GTK_ENTRY (w->timelimit)); sscanf (tmp, "%u-%u", &(i->time_begin), &(i->time_end)); i->bw_dl = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->bw_dl)); i->bw_ul = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->bw_ul)); i->quota_files = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->quota_files)); i->quota_size = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->quota_size)); i->ul_ratio = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->ul_ratio)); i->dl_ratio = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->dl_ratio)); i->per_user_max = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w->simsess)); i->allow_local_ip = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->loc_allow))); i->deny_local_ip = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->loc_deny))); i->allow_client_ip = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->cli_allow))); i->deny_client_ip = g_strdup (gtk_entry_get_text (GTK_ENTRY (w->cli_deny))); return i; } static void setup_optmenus (void) { GtkWidget *menu; GtkWidget *opt_menu; GList *IDs; opt_menu = UW("optmenu_uid"); IDs = sys_get_user_ids(); menu = gui_create_system_account_menu(IDs); gtk_option_menu_remove_menu (GTK_OPTION_MENU (opt_menu)); gtk_option_menu_set_menu (GTK_OPTION_MENU (opt_menu), menu); /* Keep the list attached to the menu for fast access in the callbacks */ g_object_set_data_full (G_OBJECT (opt_menu), "items", IDs, (GDestroyNotify) system_account_list_free); opt_menu = UW("optmenu_gid"); IDs = sys_get_group_ids(); menu = gui_create_system_account_menu(IDs); gtk_option_menu_remove_menu (GTK_OPTION_MENU (opt_menu)); gtk_option_menu_set_menu (GTK_OPTION_MENU (opt_menu), menu); g_object_set_data_full (G_OBJECT (opt_menu), "items", IDs, (GDestroyNotify) system_account_list_free); g_object_set_data (G_OBJECT (UW("usermanager")), "editing", GINT_TO_POINTER (FALSE)); } static void setup_treeview (void) { GtkTreeView *tree; GtkListStore *model; GtkCellRenderer *renderer; GtkTreeViewColumn *column; const gchar *titles[N_USRMAN_COLUMNS] = { "", _("Username"), _("Real Name") }; /* Set-up treeview */ tree = GTK_TREE_VIEW (UW("tree_userlist")); model = gtk_list_store_new (N_USRMAN_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (model)); g_object_unref (G_OBJECT (model)); gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)), GTK_SELECTION_SINGLE); renderer = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "pixbuf", COL_USRMAN_ICON, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes (titles[1], renderer, "text", COL_USRMAN_LOGIN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes (titles[2], renderer, "text", COL_USRMAN_REALNAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); } static void select_first_user (void) { static GtkWidget *tree_userman = NULL; static GtkTreeSelection *sel = NULL; GtkTreePath *path; if (!tree_userman) { tree_userman = UW("tree_userlist"); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_userman)); } path = gtk_tree_path_new_from_string ("0"); /* First item */ gtk_tree_selection_select_path (sel, path); gtk_tree_path_free (path); g_signal_emit_by_name ((gpointer) tree_userman, "cursor_changed", tree_userman, NULL); } static void add_to_users_list (PGuiUsermanRow line) { GtkTreeIter iter; static GtkWidget *tree = NULL; static GtkTreeModel *model = NULL; if (!tree) { tree = UW("tree_userlist"); model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree)); } gtk_list_store_append (GTK_LIST_STORE (model), &iter); gtk_list_store_set (GTK_LIST_STORE (model), &iter, COL_USRMAN_ICON, line.icon, COL_USRMAN_LOGIN, line.login, COL_USRMAN_REALNAME, line.realname, -1); } static void clear_users_list (void) { static GtkWidget *tree_userman = NULL; static GtkTreeModel *model = NULL; if (!tree_userman) { tree_userman = UW("tree_userlist"); model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_userman)); } gtk_list_store_clear (GTK_LIST_STORE (model)); } /* Case insensitive compare between two (PAvailableUser) users */ static gint userlist_compare_available_users (gconstpointer p1, gconstpointer p2) { PAvailableUser *u1, *u2; gchar *s1, *s2; gint rv; u1 = (PAvailableUser *) p1; u2 = (PAvailableUser *) p2; s1 = g_utf8_collate_key (u1->login, -1); s2 = g_utf8_collate_key (u2->login, -1); rv = strcmp (s1, s2); g_free (s1); g_free (s2); return rv; } /** GLOBAL FUNCTIONS **/ void usr_select_user (const gchar *user) { static GtkWidget *tree_userman = NULL; static GtkTreeModel *model = NULL; static GtkTreeSelection *sel = NULL; GtkTreeIter iter; gboolean more, found = FALSE; gchar *fetched_user; if (!tree_userman) { tree_userman = UW("tree_userlist"); model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_userman)); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_userman)); } more = gtk_tree_model_get_iter_first (model, &iter); while (more) { gtk_tree_model_get (model, &iter, COL_USR_USER, &fetched_user, -1); if (g_str_equal (fetched_user, user)) { found = TRUE; break; } more = gtk_tree_model_iter_next (model, &iter); } if (found) { gtk_tree_selection_select_iter (sel, &iter); g_signal_emit_by_name ((gpointer) tree_userman, "cursor-changed", tree_userman, NULL); } } gint usr_fill_users_list (void) { GList *user_list = NULL, *node; gint ret = 0; static GdkPixbuf *icon_usr = NULL; PGuiUsermanRow line; PAvailableUser *usr; if (!icon_usr) icon_usr = create_pixbuf ("user.png"); clear_users_list (); user_list = usr_get_available_users (NULL); user_list = g_list_sort (user_list, (GCompareFunc) userlist_compare_available_users); node = user_list; line.icon = icon_usr; while (node) { ret++; usr = (PAvailableUser *) node->data; line.login = usr->login; line.realname = usr->realname; add_to_users_list (line); g_free (line.login); g_free (line.realname); g_free (node->data); node = g_list_next (node); } g_list_free (user_list); return ret; } void usr_widgets_set_active_state (gboolean active) { struct usrman_info_widgets *w; w = get_widgets (); // gtk_widget_set_sensitive (w->login, active); gtk_widget_set_sensitive (w->realname, active); gtk_widget_set_sensitive (w->e_uid, active); gtk_widget_set_sensitive (w->e_gid, active); gtk_widget_set_sensitive (w->chk_chroot, active); gtk_widget_set_sensitive (w->home, active); if (active && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w->chk_chroot))) gtk_widget_set_sensitive (w->root, active); else if (!active) gtk_widget_set_sensitive (w->root, FALSE); gtk_widget_set_sensitive (w->quota_files, active); gtk_widget_set_sensitive (w->quota_size, active); gtk_widget_set_sensitive (w->timelimit, active); gtk_widget_set_sensitive (w->simsess, active); gtk_widget_set_sensitive (w->loc_allow, active); gtk_widget_set_sensitive (w->loc_deny, active); gtk_widget_set_sensitive (w->cli_allow, active); gtk_widget_set_sensitive (w->cli_deny, active); gtk_widget_set_sensitive (w->bw_ul, active); gtk_widget_set_sensitive (w->bw_dl, active); gtk_widget_set_sensitive (w->ul_ratio, active); gtk_widget_set_sensitive (w->dl_ratio, active); gtk_widget_set_sensitive (w->btn_pwchange, active); gtk_widget_set_sensitive (w->btn_savechanges, active); gtk_widget_set_sensitive (w->btn_cancelchanges, active); gtk_widget_set_sensitive (w->btn_browse_homedir, active); gtk_widget_set_sensitive (w->btn_browse_fakeroot, active); } gboolean usr_widgets_set_info (gchar *user) { PWInfo *info; struct usrman_info_widgets *w; gchar *tmp, **t_arr; GtkWidget *menu; GList *items = NULL; gint i; gboolean found = FALSE; GError *err = NULL; info = pw_get_user_information (user, &err); if (G_UNLIKELY (!info)) { pur_log_wrn ("Error getting user information for %s: %s", user, err->message); g_error_free (err); return FALSE; } w = get_widgets (); gtk_entry_set_text (GTK_ENTRY (w->login), info->login); gtk_entry_set_text (GTK_ENTRY (w->realname), info->gecos); /* Hmm, this should be safe if g_object_get_data returns NULL upon failure */ g_free (g_object_get_data (G_OBJECT (w->btn_pwchange), "usr_password")); if (MISC_VALID_STRING (info->pwd)) g_object_set_data (G_OBJECT (w->btn_pwchange), "usr_password", g_strdup (info->pwd)); else g_object_set_data (G_OBJECT (w->btn_pwchange), "usr_password", NULL); t_arr = g_strsplit (info->home, "/./", 2); if (t_arr[1] != NULL) { /* User is chroot'ed */ if (t_arr[1]) tmp = g_strdup_printf ("%s/%s", t_arr[0], t_arr[1]); else tmp = g_strdup (t_arr[0]); gtk_entry_set_text (GTK_ENTRY (w->home), tmp); g_free (tmp); tmp = g_strdup (t_arr[0]); gtk_entry_set_text (GTK_ENTRY (w->root), tmp); g_free (tmp); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w->chk_chroot), TRUE); } else { /* No chroot */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w->chk_chroot), FALSE); gtk_entry_set_text (GTK_ENTRY (w->home), info->home); gtk_entry_set_text (GTK_ENTRY (w->root), ""); } g_strfreev (t_arr); tmp = g_strdup_printf ("%04u-%04u", info->time_begin, info->time_end); gtk_entry_set_text (GTK_ENTRY (w->timelimit), tmp); g_free (tmp); gtk_entry_set_text (GTK_ENTRY (w->loc_allow), info->allow_local_ip); gtk_entry_set_text (GTK_ENTRY (w->loc_deny), info->deny_local_ip); gtk_entry_set_text (GTK_ENTRY (w->cli_allow), info->allow_client_ip); gtk_entry_set_text (GTK_ENTRY (w->cli_deny), info->deny_client_ip); /* UID / GID */ menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (w->e_uid)); items = (GList *) g_object_get_data (G_OBJECT (w->e_uid), "items"); i = 0; found = FALSE; while (items) { if (info->uid == ((SystemAccount *) items->data)->id) { found = TRUE; break; } i++; items = g_list_next (items); } if (found) { gtk_option_menu_set_history (GTK_OPTION_MENU (w->e_uid), i); gtk_widget_hide (w->lbl_invalid_uid); } else { gtk_option_menu_set_history (GTK_OPTION_MENU (w->e_uid), 0); gtk_widget_show (w->lbl_invalid_uid); } menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (w->e_gid)); items = (GList *) g_object_get_data (G_OBJECT (w->e_gid), "items"); i = 0; found = FALSE; while (items) { if (info->gid == ((SystemAccount *) items->data)->id) { found = TRUE; break; } i++; items = g_list_next (items); } if (found) { gtk_option_menu_set_history (GTK_OPTION_MENU (w->e_gid), i); gtk_widget_hide (w->lbl_invalid_gid); } else { gtk_option_menu_set_history (GTK_OPTION_MENU (w->e_gid), 0); gtk_widget_show (w->lbl_invalid_gid); } gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->bw_ul), (gdouble) info->bw_ul); gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->bw_dl), (gdouble) info->bw_dl); gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->quota_files), (gdouble) info->quota_files); gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->quota_size), (gdouble) info->quota_size); gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->ul_ratio), (gdouble) info->ul_ratio); gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->dl_ratio), (gdouble) info->dl_ratio); gtk_spin_button_set_value (GTK_SPIN_BUTTON (w->simsess), (gdouble) info->per_user_max); free_pwstruct (info); return TRUE; } gboolean usr_user_exists (const gchar *user) { GError *err = NULL; if (!user || strlen (user) < 1) return FALSE; if (!pw_user_exists (user, &err)) { if (err) { pur_log_wrn ("Error checking for user %s: %s", user, err->message); g_error_free (err); } return FALSE; } return TRUE; } GtkWidget *usr_init_usermanager_window (GtkWidget *parent_window) { static GtkWidget *window = NULL; if (!window) { window = create_usermanager (); setup_treeview (); setup_optmenus (); } usr_fill_users_list (); select_first_user (); gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (parent_window)); return window; } #if FALSE gboolean usr_manager_check_prerequisites (void) { static gboolean first_time = TRUE; gboolean need_group, need_user, ret; gchar *str; gint val; if (first_time == FALSE) return TRUE; pur_log_dbg ("usr_manager: First time run!"); if (!g_file_test (cfg.pwfile, G_FILE_TEST_EXISTS)) { /* No password-files found */ ret = gui_display_confirmdialog (_("Create Password File?"), _("The file containing the login-names for virtual users could not be found. You need this file in order to create and edit ftp-users.\n" "Do you want to create this file?"), _("_Yes, Create File"), NULL, MW("main_window")); if (ret == GTK_RESPONSE_YES) { if (misc_create_passwd_file () == FALSE) { /* Couldn't create password file. Report error to user */ str = g_strdup_printf (_("There was an error when trying to create password file [%s].\n" "The error reported was: '%s'"), cfg.pwfile, g_strerror (errno)); gui_display_msgdialog (_("File Creation Failed"), str, MSGDLG_TYPE_ERROR, MW("main_window")); return FALSE; } } else return FALSE; } else if ((val = access (cfg.pwfile, R_OK | W_OK)) != 0) { if (val == -1) pur_log_err ("access(%s, R_OK | W_OK) failed: %s", cfg.pwfile, g_strerror (errno)); /* We didn't have permission to read/write to the password file */ gui_display_msgdialog (_("Permission Denied"), _("You don't have permission to read and write to the password file." "This probably means that you have to run PureAdmin as root before beeing able to manage " "your users."), MSGDLG_TYPE_ERROR, MW("main_window")); return FALSE; } need_group = need_user = FALSE; /* Check if there exist a dedicated ftpgroup and ftpuser */ if (cfg.default_gid < 1) need_group = TRUE; if (cfg.default_uid < 1) need_user = TRUE; if (cfg.seen_usrdlg_welcome == FALSE && (need_user || need_group)) { GError *err = NULL; ret = gui_display_confirmdialog (_("Create User and Group"), _("It seems that you do not have a dedicated ftp-user and -group to use with the FTP users.\n" "Do you want to create ftpgroup and ftpuser and assign them as default for new users?"), _("_Yes, Create Account"), NULL, MW("main_window")); if (ret == GTK_RESPONSE_YES) { ret = misc_create_system_account (need_user, need_group, &err); if (!ret) { gui_display_msgdialog (_("Account Creation Failed"), _("PureAdmin was unable to create the system-accounts. You will have to create them manually. " "Use the appropriate tools for your distribution and read README.VirtualUsers distributed " "with the PureFTPd package."), MSGDLG_TYPE_ERROR, MW("main_window")); pur_log_err ("Error creating system accounts: %s", err->message); g_error_free (err); err = NULL; /* We want to show this dialog again, so we return here, before first_time is set to TRUE */ return FALSE; } } if (need_group) cfg.default_gid = cfg_find_ftpgroup_gid (); if (need_user) cfg.default_uid = cfg_find_ftpuser_uid (); cfg.seen_usrdlg_welcome = TRUE; } first_time = FALSE; return TRUE; } #endif gboolean usr_remove_user (const gchar *user, GError **err) { g_return_val_if_fail (err == NULL || *err == NULL, FALSE); return pw_remove_user (user, err); } /* Adds a user into the db. * arguments: * user: The user to add * passwd: The password for the user */ gboolean usr_add_user (const gchar *user, const gchar *passwd, GError **err) { g_return_val_if_fail (err == NULL || *err == NULL, FALSE); return pw_add_user (user, passwd, err); } gboolean usr_save_user_info (GError **err) { PWInfo *i; gint ret; g_return_val_if_fail (err == NULL || *err == NULL, FALSE); i = usr_widgets_get_info (); if (i == NULL || !MISC_VALID_STRING (i->login)) { pur_log_err ("Invalid information structure"); g_set_error (err, PUREADMIN_USERMANAGER_ERROR, PA_USR_ERROR_FAILED, "Couldn't get information from GUI"); return FALSE; } ret = pw_set_user_information (i, err); free_pwstruct (i); return ret; } GList *usr_get_available_users (GError **err) { g_return_val_if_fail (err == NULL || *err == NULL, NULL); return pw_get_available_users (err); }