diff options
Diffstat (limited to 'plugins/exchange-account-setup/exchange-delegates.c')
-rw-r--r-- | plugins/exchange-account-setup/exchange-delegates.c | 972 |
1 files changed, 0 insertions, 972 deletions
diff --git a/plugins/exchange-account-setup/exchange-delegates.c b/plugins/exchange-account-setup/exchange-delegates.c deleted file mode 100644 index c868eb64b9..0000000000 --- a/plugins/exchange-account-setup/exchange-delegates.c +++ /dev/null @@ -1,972 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Copyright (C) 2002-2004 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -/* ExchangeDelegates: Exchange delegate handling. - * - * FIXME: make this instant-apply - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "exchange-delegates.h" -#include "exchange-delegates-user.h" -#include "exchange-account.h" -#include "e2k-propnames.h" -#include "e2k-security-descriptor.h" -#include "e2k-sid.h" -#include "e2k-uri.h" -#include "e2k-user-dialog.h" -#include "e2k-utils.h" - -#include <e-util/e-dialog-utils.h> -#include <glade/glade-xml.h> -#include <gtk/gtkbox.h> -#include <gtk/gtkcellrenderertext.h> -#include <gtk/gtkliststore.h> -#include <gtk/gtkmessagedialog.h> -#include <gtk/gtktreeselection.h> -#include <gtk/gtktreeview.h> - -typedef struct { - const char *uri; - E2kSecurityDescriptor *sd; - gboolean changed; -} ExchangeDelegatesFolder; - -typedef struct { - ExchangeAccount *account; - char *self_dn; - - GladeXML *xml; - GtkWidget *dialog, *parent; - - GtkListStore *model; - GtkWidget *table; - - GByteArray *creator_entryid; - GPtrArray *users, *added_users, *removed_users; - gboolean loaded_folders; - ExchangeDelegatesFolder folder[EXCHANGE_DELEGATES_LAST]; - ExchangeDelegatesFolder freebusy_folder; -} ExchangeDelegates; - -extern const char *exchange_delegates_user_folder_names[]; - -const char *exchange_localfreebusy_path = "NON_IPM_SUBTREE/Freebusy%20Data/LocalFreebusy.EML"; - -static void set_perms_for_user (ExchangeDelegatesUser *user, gpointer user_data); - -static void -set_sd_for_href (ExchangeDelegates *delegates, - const char *href, - E2kSecurityDescriptor *sd) -{ - int i; - - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { - if (!delegates->folder[i].uri) - continue; - - if (!strcmp (href, delegates->folder[i].uri)) { - delegates->folder[i].sd = sd; - return; - } - } - - /* else, it's the freebusy folder */ - delegates->freebusy_folder.uri = g_strdup (href); - delegates->freebusy_folder.sd = sd; -} - -/* Given an array of ExchangeDelegatesUser containing display names - * and entryids, and an array of E2kSecurityDescriptors containing - * SIDs (which contain display names), add SIDs to the delegates. In - * the easy case, we can just match the SIDs up with their - * corresponding user by display name. However, there are two things - * that can go wrong: - * - * 1. Some users may have been removed from the SDs - * 2. Two users may have the same display name - * - * In both cases, we fall back to using the GC. - */ -static gboolean -fill_in_sids (ExchangeDelegates *delegates) -{ - int u, u2, sd, needed_sids; - ExchangeDelegatesUser *user, *user2; - GList *sids, *s; - E2kSid *sid; - E2kGlobalCatalog *gc; - E2kGlobalCatalogStatus status; - E2kGlobalCatalogEntry *entry; - gboolean ok = TRUE; - - needed_sids = 0; - - /* Mark users with duplicate names and count the number of - * non-duplicate names. - */ - for (u = 0; u < delegates->users->len; u++) { - user = delegates->users->pdata[u]; - if (user->sid == (E2kSid *)-1) - continue; - for (u2 = u + 1; u2 < delegates->users->len; u2++) { - user2 = delegates->users->pdata[u2]; - if (!strcmp (user->display_name, user2->display_name)) - user->sid = user2->sid = (E2kSid *)-1; - } - if (!user->sid) - needed_sids++; - } - - /* Scan security descriptors trying to match SIDs until we're - * not expecting to find any more. - */ - for (sd = 0; sd < EXCHANGE_DELEGATES_LAST && needed_sids; sd++) { - sids = e2k_security_descriptor_get_sids (delegates->folder[sd].sd); - for (s = sids; s && needed_sids; s = s->next) { - sid = s->data; - for (u = 0; u < delegates->users->len; u++) { - user = delegates->users->pdata[u]; - if (user->sid) - continue; - if (!strcmp (user->display_name, - e2k_sid_get_display_name (sid))) { - user->sid = sid; - g_object_ref (sid); - needed_sids--; - } - } - } - g_list_free (sids); - } - - /* Now for each user whose SID hasn't yet been found, look it up. */ - gc = exchange_account_get_global_catalog (delegates->account); - for (u = 0; u < delegates->users->len; u++) { - user = delegates->users->pdata[u]; - if (user->sid && user->sid != (E2kSid *)-1) - continue; - - status = e2k_global_catalog_lookup ( - gc, NULL, /* FIXME: cancellable */ - E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN, - e2k_entryid_to_dn (user->entryid), - E2K_GLOBAL_CATALOG_LOOKUP_SID, &entry); - if (status != E2K_GLOBAL_CATALOG_OK) { - user->sid = NULL; - ok = FALSE; - continue; - } - user->sid = entry->sid; - g_object_ref (user->sid); - e2k_global_catalog_entry_free (gc, entry); - } - - return ok; -} - -static const char *sd_props[] = { - E2K_PR_EXCHANGE_SD_BINARY, - E2K_PR_EXCHANGE_SD_XML -}; -static const int n_sd_props = sizeof (sd_props) / sizeof (sd_props[0]); - -/* Read the folder security descriptors and match them up with the - * list of delegates. - */ -static gboolean -get_folder_security (ExchangeDelegates *delegates) -{ - GPtrArray *hrefs; - E2kContext *ctx; - E2kHTTPStatus status; - E2kResultIter *iter; - E2kResult *result; - xmlNode *xml_form; - GByteArray *binary_form; - ExchangeDelegatesUser *user; - guint32 perms; - int i, u; - - /* If we've been here before, just return the success or - * failure result from last time. - */ - if (delegates->freebusy_folder.uri) - return delegates->loaded_folders; - - if (!exchange_account_get_global_catalog (delegates->account)) { - e_notice (delegates->table, GTK_MESSAGE_ERROR, - _("No Global Catalog server configured for this account.\nUnable to edit delegates.")); - return FALSE; - } - - ctx = exchange_account_get_context (delegates->account); - - hrefs = g_ptr_array_new (); - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { - delegates->folder[i].uri = exchange_account_get_standard_uri ( - delegates->account, exchange_delegates_user_folder_names[i]); - if (delegates->folder[i].uri) { - g_ptr_array_add (hrefs, (char *)e2k_uri_relative ( - delegates->account->home_uri, - delegates->folder[i].uri)); - } - } - g_ptr_array_add (hrefs, (char *)exchange_localfreebusy_path); - - iter = e2k_context_bpropfind_start ( - ctx, NULL, delegates->account->home_uri, - (const char **)hrefs->pdata, hrefs->len, - sd_props, n_sd_props); - g_ptr_array_free (hrefs, TRUE); - - while ((result = e2k_result_iter_next (iter))) { - xml_form = e2k_properties_get_prop (result->props, - E2K_PR_EXCHANGE_SD_XML); - binary_form = e2k_properties_get_prop (result->props, - E2K_PR_EXCHANGE_SD_BINARY); - - if (xml_form && binary_form) { - set_sd_for_href (delegates, result->href, - e2k_security_descriptor_new (xml_form, binary_form)); - } - } - status = e2k_result_iter_free (iter); - - if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) { - e_notice (delegates->table, GTK_MESSAGE_ERROR, - _("Could not read folder permissions.\nUnable to edit delegates.")); - return FALSE; - } - - if (!fill_in_sids (delegates)) { - delegates->loaded_folders = FALSE; - e_notice (delegates->table, GTK_MESSAGE_ERROR, - _("Could not determine folder permissions for delegates.\nUnable to edit delegates.")); - return FALSE; - } - - /* Fill in delegate structures from the security descriptors */ - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { - for (u = 0; u < delegates->users->len; u++) { - user = delegates->users->pdata[u]; - perms = e2k_security_descriptor_get_permissions ( - delegates->folder[i].sd, user->sid); - user->role[i] = e2k_permissions_role_find (perms); - } - } - - delegates->loaded_folders = TRUE; - return TRUE; -} - - -static const char *delegation_props[] = { - PR_DELEGATES_DISPLAY_NAMES, - PR_DELEGATES_ENTRYIDS, - PR_DELEGATES_SEE_PRIVATE, - PR_CREATOR_ENTRYID -}; -static const int n_delegation_props = sizeof (delegation_props) / sizeof (delegation_props[0]); - -/* Fetch the list of delegates from the freebusy message. */ -static gboolean -get_user_list (ExchangeDelegates *delegates) -{ - E2kContext *ctx; - E2kResultIter *iter; - E2kResult *result; - GPtrArray *display_names, *entryids, *privflags; - GByteArray *entryid; - ExchangeDelegatesUser *user; - int i; - - ctx = exchange_account_get_context (delegates->account); - iter = e2k_context_bpropfind_start (ctx, NULL, - delegates->account->home_uri, - &exchange_localfreebusy_path, 1, - delegation_props, n_delegation_props); - result = e2k_result_iter_next (iter); - if (!result || !E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status)) { - e2k_result_iter_free (iter); - return FALSE; - } - - delegates->users = g_ptr_array_new (); - delegates->added_users = g_ptr_array_new (); - delegates->removed_users = g_ptr_array_new (); - - display_names = e2k_properties_get_prop (result->props, PR_DELEGATES_DISPLAY_NAMES); - entryids = e2k_properties_get_prop (result->props, PR_DELEGATES_ENTRYIDS); - privflags = e2k_properties_get_prop (result->props, PR_DELEGATES_SEE_PRIVATE); - - entryid = e2k_properties_get_prop (result->props, PR_CREATOR_ENTRYID); - delegates->creator_entryid = g_byte_array_new (); - g_byte_array_append (delegates->creator_entryid, entryid->data, entryid->len); - - if (!display_names || !entryids || !privflags) { - e2k_result_iter_free (iter); - return TRUE; - } - - for (i = 0; i < display_names->len && i < entryids->len && i < privflags->len; i++) { - user = exchange_delegates_user_new (display_names->pdata[i]); - user->see_private = privflags->pdata[i] && atoi (privflags->pdata[i]); - entryid = entryids->pdata[i]; - user->entryid = g_byte_array_new (); - g_byte_array_append (user->entryid, entryid->data, entryid->len); - - g_signal_connect (user, "edited", G_CALLBACK (set_perms_for_user), delegates); - - g_ptr_array_add (delegates->users, user); - } - - e2k_result_iter_free (iter); - return TRUE; -} - -/* Add or remove a delegate. Everyone must be in one of three states: - * 1. only in users (because they started and ended there) - * 2. in users and added_users (because they weren't in - * users to begin with, but got added) - * 3. only in removed_users (because they were in users to - * begin with and got removed). - * If you're added and then removed, or removed and then added, you have - * to end up in state 1. That's what this is for. - */ -static void -add_remove_user (ExchangeDelegatesUser *user, - GPtrArray *to_array, GPtrArray *from_array) -{ - ExchangeDelegatesUser *match; - int i; - - for (i = 0; i < from_array->len; i++) { - match = from_array->pdata[i]; - if (e2k_sid_binary_sid_equal (e2k_sid_get_binary_sid (match->sid), - e2k_sid_get_binary_sid (user->sid))) { - g_ptr_array_remove_index_fast (from_array, i); - g_object_unref (match); - return; - } - } - - g_ptr_array_add (to_array, user); - g_object_ref (user); -} - -static void -set_perms_for_user (ExchangeDelegatesUser *user, gpointer user_data) -{ - ExchangeDelegates *delegates = user_data; - int i, role; - guint32 perms; - - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { - perms = e2k_permissions_role_get_perms (user->role[i]); - e2k_security_descriptor_set_permissions (delegates->folder[i].sd, - user->sid, perms); - } - role = user->role[EXCHANGE_DELEGATES_CALENDAR]; - if (role == E2K_PERMISSIONS_ROLE_AUTHOR) - role = E2K_PERMISSIONS_ROLE_EDITOR; - perms = e2k_permissions_role_get_perms (role); - e2k_security_descriptor_set_permissions (delegates->freebusy_folder.sd, - user->sid, perms); -} - -static void -add_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - ExchangeDelegates *delegates = data; - E2kGlobalCatalog *gc; - GtkWidget *dialog, *parent_window; - const char *delegate_exchange_dn; - char *email; - ExchangeDelegatesUser *user, *match; - int response, u; - GtkTreeIter iter; - - if (!get_folder_security (delegates)) - return; - - gc = exchange_account_get_global_catalog (delegates->account); - - parent_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); - dialog = e2k_user_dialog_new (parent_window, - _("Delegate To:"), _("Delegate To")); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response != GTK_RESPONSE_OK) { - gtk_widget_destroy (dialog); - return; - } - email = e2k_user_dialog_get_user (E2K_USER_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - if (email == NULL) - return; - - user = exchange_delegates_user_new_from_gc (gc, email, - delegates->creator_entryid); - if (!user) { - e_notice (parent_window, GTK_MESSAGE_ERROR, - _("Could not make %s a delegate"), email); - g_free (email); - return; - } - g_free (email); - - delegate_exchange_dn = e2k_entryid_to_dn (user->entryid); - if (delegate_exchange_dn && !g_ascii_strcasecmp (delegate_exchange_dn, delegates->account->legacy_exchange_dn)) { - g_object_unref (user); - e_notice (parent_window, GTK_MESSAGE_ERROR, - _("You cannot make yourself your own delegate")); - return; - } - - for (u = 0; u < delegates->users->len; u++) { - match = delegates->users->pdata[u]; - if (e2k_sid_binary_sid_equal (e2k_sid_get_binary_sid (user->sid), - e2k_sid_get_binary_sid (match->sid))) { - e_notice (parent_window, GTK_MESSAGE_INFO, - _("%s is already a delegate"), - user->display_name); - g_object_unref (user); - exchange_delegates_user_edit (match, parent_window); - return; - } - } - - if (!exchange_delegates_user_edit (user, parent_window)) { - g_object_unref (user); - return; - } - set_perms_for_user (user, delegates); - g_signal_connect (user, "edited", - G_CALLBACK (set_perms_for_user), delegates); - - add_remove_user (user, delegates->added_users, delegates->removed_users); - g_ptr_array_add (delegates->users, user); - - /* Add the user to the table */ - gtk_list_store_append (delegates->model, &iter); - gtk_list_store_set (delegates->model, &iter, - 0, user->display_name, - -1); -} - -static int -get_selected_row (GtkWidget *tree_view, GtkTreeIter *iter) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreePath *path; - int *indices, row; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); - if (!gtk_tree_selection_get_selected (selection, &model, iter)) - return -1; - - path = gtk_tree_model_get_path (model, iter); - indices = gtk_tree_path_get_indices (path); - row = indices[0]; - gtk_tree_path_free (path); - - return row; -} - -static void -edit_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - ExchangeDelegates *delegates = data; - GtkWidget *parent_window; - GtkTreeIter iter; - int row; - - if (!get_folder_security (delegates)) - return; - - row = get_selected_row (delegates->table, &iter); - g_return_if_fail (row >= 0 && row < delegates->users->len); - - parent_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); - exchange_delegates_user_edit (delegates->users->pdata[row], - parent_window); -} - -static gboolean -table_click_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) -{ - ExchangeDelegates *delegates = data; - GtkWidget *parent_window; - GtkTreeIter iter; - int row; - - if (event->type != GDK_2BUTTON_PRESS) - return FALSE; - - row = get_selected_row (delegates->table, &iter); - if (row < 0 || row >= delegates->users->len) - return FALSE; - - if (!get_folder_security (delegates)) - return FALSE; - - parent_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); - exchange_delegates_user_edit (delegates->users->pdata[row], - parent_window); - return TRUE; -} - -static void -remove_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - ExchangeDelegates *delegates = data; - ExchangeDelegatesUser *user; - GtkWidget *dialog; - int row, btn, i; - GtkTreeIter iter; - - if (!get_folder_security (delegates)) - return; - - row = get_selected_row (delegates->table, &iter); - g_return_if_fail (row >= 0 && row < delegates->users->len); - - user = delegates->users->pdata[row]; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - _("Remove the delegate %s?"), - user->display_name); - e_dialog_set_transient_for (GTK_WINDOW (dialog), widget); - - btn = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - if (btn != GTK_RESPONSE_YES) - return; - - add_remove_user (user, delegates->removed_users, delegates->added_users); - - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { - e2k_security_descriptor_remove_sid (delegates->folder[i].sd, - user->sid); - } - e2k_security_descriptor_remove_sid (delegates->freebusy_folder.sd, - user->sid); - - /* Remove the user from the table */ - gtk_list_store_remove (delegates->model, &iter); - g_ptr_array_remove_index (delegates->users, row); - g_object_unref (user); -} - - -static gboolean -proppatch_sd (E2kContext *ctx, ExchangeDelegatesFolder *folder) -{ - GByteArray *binsd; - E2kProperties *props; - const char *href = ""; - E2kResultIter *iter; - E2kResult *result; - E2kHTTPStatus status; - - binsd = e2k_security_descriptor_to_binary (folder->sd); - if (!binsd) - return FALSE; - - props = e2k_properties_new (); - e2k_properties_set_binary (props, E2K_PR_EXCHANGE_SD_BINARY, binsd); - - iter = e2k_context_bproppatch_start (ctx, NULL, folder->uri, - &href, 1, props, FALSE); - e2k_properties_free (props); - - result = e2k_result_iter_next (iter); - if (result) { - status = result->status; - e2k_result_iter_free (iter); - } else - status = e2k_result_iter_free (iter); - - return E2K_HTTP_STATUS_IS_SUCCESSFUL (status); -} - -static gboolean -get_user_dn (E2kGlobalCatalog *gc, ExchangeDelegatesUser *user) -{ - E2kGlobalCatalogEntry *entry; - E2kGlobalCatalogStatus status; - const char *exchange_dn; - - exchange_dn = e2k_entryid_to_dn (user->entryid); - status = e2k_global_catalog_lookup ( - gc, NULL, /* FIXME: cancellable */ - E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN, - exchange_dn, 0, &entry); - if (status != E2K_GLOBAL_CATALOG_OK) - return FALSE; - - user->dn = g_strdup (entry->dn); - e2k_global_catalog_entry_free (gc, entry); - return TRUE; -} - -static void -delegates_apply (ExchangeDelegates *delegates) -{ - ExchangeDelegatesUser *user; - E2kGlobalCatalog *gc; - E2kContext *ctx; - GPtrArray *display_names, *entryids, *privflags; - GByteArray *entryid_dup; - char *error = NULL; - E2kProperties *props; - int i, status; - - if (!delegates->loaded_folders) - return; - - /* We can't do this atomically/transactionally, so we need to - * make sure that if we fail at any step, things are still in - * a semi-consistent state. So we do: - * - * 1. Remove old delegates from AD - * 2. Update LocalFreebusy.EML (the canonical list of delegates) - * 3. Add new delegates to AD - * 4. Update security descriptors - * - * If step 1 fails, nothing is changed. - * - * If step 2 fails, delegates who should have been removed - * will have been removed from AD but nothing else, so they - * will still show up as being delegates and the user can try - * to remove them again later. - * - * If step 3 fails, delegates who should have been added will - * not be in AD, but will be listed as delegates, so the user - * can remove them and try adding them again later. - * - * If step 4 fails, the user can still correct the folder - * permissions by hand. - */ - - gc = exchange_account_get_global_catalog (delegates->account); - if (!gc) { - error = g_strdup (_("Could not access Active Directory")); - goto done; - } - - if ((delegates->removed_users || delegates->added_users) && !delegates->self_dn) { - E2kGlobalCatalog *gc; - E2kGlobalCatalogStatus status; - E2kGlobalCatalogEntry *entry; - - gc = exchange_account_get_global_catalog (delegates->account); - status = e2k_global_catalog_lookup ( - gc, NULL, /* FIXME: cancellable */ - E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN, - delegates->account->legacy_exchange_dn, 0, &entry); - if (status != E2K_GLOBAL_CATALOG_OK) { - error = g_strdup (_("Could not find self in Active Directory")); - goto done; - } - - delegates->self_dn = g_strdup (entry->dn); - e2k_global_catalog_entry_free (gc, entry); - } - - /* 1. Remove old delegates from AD */ - while (delegates->removed_users && delegates->removed_users->len) { - user = delegates->removed_users->pdata[0]; - if (!user->dn && !get_user_dn (gc, user)) { - error = g_strdup_printf ( - _("Could not find delegate %s in Active Directory"), - user->display_name); - goto done; - } - - /* FIXME: cancellable */ - status = e2k_global_catalog_remove_delegate (gc, NULL, - delegates->self_dn, - user->dn); - if (status != E2K_GLOBAL_CATALOG_OK && - status != E2K_GLOBAL_CATALOG_NO_DATA) { - error = g_strdup_printf ( - _("Could not remove delegate %s"), - user->display_name); - goto done; - } - - g_object_unref (user); - g_ptr_array_remove_index_fast (delegates->removed_users, 0); - } - - /* 2. Update LocalFreebusy.EML */ - ctx = exchange_account_get_context (delegates->account); - - if (delegates->users->len) { - display_names = g_ptr_array_new (); - entryids = g_ptr_array_new (); - privflags = g_ptr_array_new (); - - for (i = 0; i < delegates->users->len; i++) { - user = delegates->users->pdata[i]; - g_ptr_array_add (display_names, g_strdup (user->display_name)); - entryid_dup = g_byte_array_new (); - g_byte_array_append (entryid_dup, user->entryid->data, - user->entryid->len); - g_ptr_array_add (entryids, entryid_dup); - g_ptr_array_add (privflags, g_strdup_printf ("%d", user->see_private)); - } - - props = e2k_properties_new (); - e2k_properties_set_string_array ( - props, PR_DELEGATES_DISPLAY_NAMES, display_names); - e2k_properties_set_binary_array ( - props, PR_DELEGATES_ENTRYIDS, entryids); - e2k_properties_set_int_array ( - props, PR_DELEGATES_SEE_PRIVATE, privflags); - } else if (delegates->removed_users) { - props = e2k_properties_new (); - e2k_properties_remove (props, PR_DELEGATES_DISPLAY_NAMES); - e2k_properties_remove (props, PR_DELEGATES_ENTRYIDS); - e2k_properties_remove (props, PR_DELEGATES_SEE_PRIVATE); - } else - props = NULL; - - if (props) { - E2kResultIter *iter; - E2kResult *result; - - iter = e2k_context_bproppatch_start ( - ctx, NULL, delegates->account->home_uri, - &exchange_localfreebusy_path, 1, - props, FALSE); - e2k_properties_free (props); - - result = e2k_result_iter_next (iter); - if (result) { - status = result->status; - e2k_result_iter_free (iter); - } else - status = e2k_result_iter_free (iter); - - if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) { - error = g_strdup (_("Could not update list of delegates.")); - goto done; - } - } - - /* 3. Add new delegates to AD */ - while (delegates->added_users && delegates->added_users->len) { - user = delegates->added_users->pdata[0]; - /* An added user must have come from the GC so - * we know user->dn is set. - */ - /* FIXME: cancellable */ - status = e2k_global_catalog_add_delegate (gc, NULL, - delegates->self_dn, - user->dn); - if (status != E2K_GLOBAL_CATALOG_OK && - status != E2K_GLOBAL_CATALOG_EXISTS) { - error = g_strdup_printf ( - _("Could not add delegate %s"), - user->display_name); - goto done; - } - g_ptr_array_remove_index_fast (delegates->added_users, 0); - g_object_unref (user); - } - - /* 4. Update security descriptors */ - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) - proppatch_sd (ctx, &delegates->folder[i]); - proppatch_sd (ctx, &delegates->freebusy_folder); - - done: - if (error) { - e_notice (delegates->table, GTK_MESSAGE_ERROR, - _("Failed to update delegates:\n%s"), error); - g_free (error); - } -} - -static void parent_destroyed (gpointer user_data, GObject *ex_parent); - -static void -delegates_destroy (ExchangeDelegates *delegates) -{ - int i; - - g_object_unref (delegates->account); - - if (delegates->parent) { - g_object_weak_unref (G_OBJECT (delegates->parent), - parent_destroyed, delegates); - } - if (delegates->dialog) - gtk_widget_destroy (delegates->dialog); - - if (delegates->model) - g_object_unref (delegates->model); - - if (delegates->self_dn) - g_free (delegates->self_dn); - if (delegates->creator_entryid) - g_byte_array_free (delegates->creator_entryid, TRUE); - - if (delegates->users) { - for (i = 0; i < delegates->users->len; i++) - g_object_unref (delegates->users->pdata[i]); - g_ptr_array_free (delegates->users, TRUE); - } - if (delegates->added_users) { - for (i = 0; i < delegates->added_users->len; i++) - g_object_unref (delegates->added_users->pdata[i]); - g_ptr_array_free (delegates->added_users, TRUE); - } - if (delegates->removed_users) { - for (i = 0; i < delegates->removed_users->len; i++) - g_object_unref (delegates->removed_users->pdata[i]); - g_ptr_array_free (delegates->removed_users, TRUE); - } - - for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { - if (delegates->folder[i].sd) - g_object_unref (delegates->folder[i].sd); - } - if (delegates->freebusy_folder.sd) - g_object_unref (delegates->freebusy_folder.sd); - if (delegates->freebusy_folder.uri) - g_free ((char *)delegates->freebusy_folder.uri); - - if (delegates->xml) - g_object_unref (delegates->xml); - - g_free (delegates); -} - - -static void -dialog_response (GtkDialog *dialog, int response, gpointer user_data) -{ - ExchangeDelegates *delegates = user_data; - - if (response == GTK_RESPONSE_OK) - delegates_apply (delegates); - delegates_destroy (delegates); -} - -static void -parent_destroyed (gpointer user_data, GObject *ex_parent) -{ - ExchangeDelegates *delegates = user_data; - - gtk_widget_destroy (delegates->dialog); - delegates_destroy (delegates); -} - -void -exchange_delegates (ExchangeAccount *account, GtkWidget *parent) -{ - ExchangeDelegates *delegates; - GtkWidget *button; - ExchangeDelegatesUser *user; - GtkTreeViewColumn *column; - GtkTreeIter iter; - int i; - - g_return_if_fail (GTK_IS_WIDGET (parent)); - g_return_if_fail (EXCHANGE_IS_ACCOUNT (account)); - - delegates = g_new0 (ExchangeDelegates, 1); - delegates->account = g_object_ref (account); - - delegates->xml = glade_xml_new (CONNECTOR_GLADEDIR "/exchange-delegates.glade", NULL, NULL); - g_return_if_fail (delegates->xml != NULL); - - delegates->dialog = glade_xml_get_widget (delegates->xml, "delegates"); - g_return_if_fail (delegates->dialog != NULL); - - g_signal_connect (delegates->dialog, "response", - G_CALLBACK (dialog_response), delegates); - - e_dialog_set_transient_for (GTK_WINDOW (delegates->dialog), parent); - delegates->parent = parent; - g_object_weak_ref (G_OBJECT (parent), parent_destroyed, delegates); - - /* Set up the buttons */ - button = glade_xml_get_widget (delegates->xml, "add_button"); - g_signal_connect (button, "clicked", - G_CALLBACK (add_button_clicked_cb), delegates); - button = glade_xml_get_widget (delegates->xml, "edit_button"); - g_signal_connect (button, "clicked", - G_CALLBACK (edit_button_clicked_cb), delegates); - button = glade_xml_get_widget (delegates->xml, "remove_button"); - g_signal_connect (button, "clicked", - G_CALLBACK (remove_button_clicked_cb), delegates); - - /* Set up the table */ - delegates->model = gtk_list_store_new (1, G_TYPE_STRING); - delegates->table = glade_xml_get_widget (delegates->xml, "delegates_table"); - column = gtk_tree_view_column_new_with_attributes ( - _("Name"), gtk_cell_renderer_text_new (), "text", 0, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (delegates->table), - column); - gtk_tree_view_set_model (GTK_TREE_VIEW (delegates->table), - GTK_TREE_MODEL (delegates->model)); - - /* Get list of delegate users */ - if (get_user_list (delegates)) { - for (i = 0; i < delegates->users->len; i++) { - user = delegates->users->pdata[i]; - - gtk_list_store_append (delegates->model, &iter); - gtk_list_store_set (delegates->model, &iter, - 0, user->display_name, - -1); - } - g_signal_connect (delegates->table, - "button_press_event", - G_CALLBACK (table_click_cb), delegates); - } else { - button = glade_xml_get_widget (delegates->xml, "add_button"); - gtk_widget_set_sensitive (button, FALSE); - button = glade_xml_get_widget (delegates->xml, "edit_button"); - gtk_widget_set_sensitive (button, FALSE); - button = glade_xml_get_widget (delegates->xml, "remove_button"); - gtk_widget_set_sensitive (button, FALSE); - - gtk_list_store_append (delegates->model, &iter); - gtk_list_store_set (delegates->model, &iter, - 0, _("Error reading delegates list."), - -1); - } - - gtk_widget_show (delegates->dialog); -} |