Index: gnome-keyring/gnome-keyring-ask.c
===================================================================
--- gnome-keyring/gnome-keyring-ask.c	(revision 1)
+++ gnome-keyring/gnome-keyring-ask.c	(working copy)
@@ -435,6 +435,96 @@
 }
 
 static void
+ask_for_change_keyring_password (void)
+{
+	char *message;
+	char *title;
+	gint response;
+	int app;
+	int keyring;
+	char *password;
+	
+	app = get_app_information ();
+	if (env_keyring_name == NULL) {
+		env_keyring_name = "";
+	}
+	keyring = get_keyring_information ();
+	g_assert (keyring != KEYRING_NAME_UNKNOWN);
+	
+	message = NULL;
+	if (app == APPLICATION_NAME_DISPLAY_AND_PATH) {
+		if (keyring == KEYRING_NAME_NORMAL) {
+			message = g_strdup_printf (_("The application '%s' (%s) wants to change the password for the '%s' keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_app_display_name, env_app_pathname, env_keyring_name);
+		} else if (keyring == KEYRING_NAME_DEFAULT) {
+			message = g_strdup_printf (_("The application '%s' (%s) wants to change the password for the default keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_app_display_name, env_app_pathname);
+		} 
+	} else if (app == APPLICATION_NAME_DISPLAY_ONLY) {
+		if (keyring == KEYRING_NAME_NORMAL) {
+			message = g_strdup_printf (_("The application '%s' wants to change the password for the '%s' keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_app_display_name, env_keyring_name);
+		} else if (keyring == KEYRING_NAME_DEFAULT) {
+			message = g_strdup_printf (_("The application '%s' wants to change the password for the default keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_app_display_name);
+		} 
+	} else if (app == APPLICATION_NAME_PATH_ONLY) {
+		if (keyring == KEYRING_NAME_NORMAL) {
+			message = g_strdup_printf (_("The application '%s' wants to change the password for the '%s' keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_app_pathname, env_keyring_name);
+		} else if (keyring == KEYRING_NAME_DEFAULT) {
+			message = g_strdup_printf (_("The application '%s' wants to change the password for the default keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_app_pathname);
+		} 
+	} else /* app == APPLICATION_NAME_UNKNOWN */ {
+		if (keyring == KEYRING_NAME_NORMAL) {
+			message = g_strdup_printf (_("An unkown application wants to change the password for the '%s' keyring. "
+						     "You have to choose the password you want to use for it."),
+						   env_keyring_name);
+		} else if (keyring == KEYRING_NAME_DEFAULT) {
+			message = g_strdup_printf (_("An unkown application wants to change the password for the default keyring. "
+						     "You have to choose the password you want to use for it."));
+		} 
+	}
+	
+	if (keyring == KEYRING_NAME_NORMAL) {
+		title = g_strdup_printf (_("Choose a new password for the '%s' keyring. "), env_keyring_name);
+	} else if (keyring == KEYRING_NAME_DEFAULT) {
+		title = g_strdup_printf (_("Choose a new password for the default keyring. "));
+	}
+
+	password = NULL;	
+	response = run_dialog (_("Change Keyring Password"),
+			       _(title),
+			       message,
+			       TRUE, TRUE, &password,
+			       GTK_RESPONSE_OK,
+			       _("_Deny"), GTK_RESPONSE_CANCEL,
+			       GTK_STOCK_OK, GTK_RESPONSE_OK,
+			       NULL);
+	g_free (message);
+	
+	if (response == GTK_RESPONSE_OK) {
+		response = GNOME_KEYRING_ASK_RESPONSE_ALLOW_ONCE;
+	} else {
+		response = GNOME_KEYRING_ASK_RESPONSE_DENY;
+	}
+	
+	if (password) {
+		printf ("%d\n%s\n", response, password);
+		g_free (password);
+	} else {
+		printf ("%d\n\n", response);
+	}
+}
+
+static void
 ask_for_default_keyring (void)
 {
 	char *message;
@@ -605,6 +695,8 @@
 		ask_for_keyring_password ();
 	} else if (strcmp (argv[1], "-n") == 0) {
 		ask_for_new_keyring_password ();
+	} else if (strcmp (argv[1], "-c") == 0) {
+		ask_for_change_keyring_password ();
 	} else if (strcmp (argv[1], "-i") == 0) {
 		ask_for_item_read_write_acccess ();
 	} else if (strcmp (argv[1], "-d") == 0) {
Index: gnome-keyring/gnome-keyring-daemon
===================================================================
Cannot display: file marked as binary type.
svn:mime-type = application/octet-stream
Index: gnome-keyring/gnome-keyring-daemon.c
===================================================================
--- gnome-keyring/gnome-keyring-daemon.c	(revision 1)
+++ gnome-keyring/gnome-keyring-daemon.c	(working copy)
@@ -50,6 +50,7 @@
 	ASK_KEYRING_PASSWORD,
 	ASK_ITEM_READ_WRITE_ACCESS,
 	ASK_NEW_KEYRING_PASSWORD,
+	ASK_CHANGE_KEYRING_PASSWORD,
 	ASK_DEFAULT_KEYRING
 };
 
@@ -565,6 +566,16 @@
 }
 
 static GnomeKeyringAccessRequest *
+access_request_for_change_keyring_password (const char *keyring_name)
+{
+	GnomeKeyringAccessRequest *access_request;
+	access_request = g_new0 (GnomeKeyringAccessRequest, 1);
+	access_request->request_type = GNOME_KEYRING_ACCESS_REQUEST_CHANGE_KEYRING_PASSWORD;
+	access_request->new_keyring = g_strdup (keyring_name);
+	return access_request;
+}
+
+static GnomeKeyringAccessRequest *
 access_request_default_keyring (void)
 {
 	GnomeKeyringAccessRequest *access_request;
@@ -613,6 +624,20 @@
 	return find_item_in_list (keyring->items, id);
 }
 
+
+static GnomeKeyringResult
+change_keyring_password ( GnomeKeyring *keyring, const char *password)
+{
+	if (keyring->locked)
+		return GNOME_KEYRING_RESULT_DENIED;
+	
+	keyring->password = g_strdup (password);
+	save_keyring_to_disk (keyring);
+	g_free (keyring->password);
+	keyring->password = NULL;
+	return GNOME_KEYRING_RESULT_OK;
+}
+
 static GnomeKeyringResult
 unlock_keyring (GnomeKeyring *keyring, const char *password)
 {
@@ -925,6 +950,7 @@
 
 }
 
+
 static gboolean
 op_create_keyring_execute (GString *packet,
 			   GString *result,
@@ -1050,6 +1076,101 @@
 	return TRUE;
 }
 
+static gboolean
+op_change_keyring_password_collect (GString *packet,
+			   GList **access_requests_out)
+{
+	GList *access_requests;
+	GnomeKeyringOpCode opcode;
+	char *keyring_name, *password;
+	GnomeKeyring *keyring;
+	
+	if (!gnome_keyring_proto_decode_op_string_string (packet,
+							  &opcode,
+							  &keyring_name,
+							  &password)) {
+		return FALSE;
+	}
+
+	access_requests = NULL;
+	
+	if (keyring_name == NULL) {
+		keyring_name = "default_keyring";
+	}
+	
+	keyring = find_keyring (keyring_name);
+	if (keyring == NULL) {
+		/* don't exist */
+		return FALSE;
+	}
+	
+	if (password == NULL) {
+		/* Let user pick password */
+		access_requests =
+			g_list_prepend (access_requests,
+					access_request_for_change_keyring_password (keyring_name));
+	}
+
+ out:
+	*access_requests_out = access_requests;
+	
+	g_free (keyring_name);
+	gnome_keyring_free_password (password);
+	
+	return TRUE;
+}
+
+static gboolean
+op_change_keyring_password_execute (GString *packet,
+			   GString *result,
+			   GnomeKeyringApplicationRef *app_ref,
+			   GList *access_requests)
+{
+	char *keyring_name, *password;
+	GnomeKeyring *keyring;
+	GnomeKeyringOpCode opcode;
+	GnomeKeyringAccessRequest *req;
+	
+	if (!gnome_keyring_proto_decode_op_string_string (packet,
+							  &opcode,
+							  &keyring_name,
+							  &password)) {
+		return FALSE;
+	}
+	g_assert (opcode == GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD);
+	
+	if (keyring_name == NULL) {
+		gnome_keyring_proto_add_uint32 (result, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+		goto out;
+	}
+	
+	keyring = find_keyring (keyring_name);
+	
+	if (password == NULL) {
+		if (access_requests != NULL) {
+			req = access_requests->data;
+			password = g_strdup (req->password);
+		}
+	}
+	
+	if (password == NULL) {
+		gnome_keyring_proto_add_uint32 (result, GNOME_KEYRING_RESULT_DENIED);
+		goto out;
+	}
+	
+	if (keyring == NULL) {
+		gnome_keyring_proto_add_uint32 (result, GNOME_KEYRING_RESULT_DENIED);
+		goto out;
+	}
+	
+	gnome_keyring_proto_add_uint32 (result, change_keyring_password (keyring, password));
+	
+ out:
+	g_free (keyring_name);
+	gnome_keyring_free_password (password);
+	
+	return TRUE;
+}
 
 static gboolean
 op_list_items_collect (GString *packet,
@@ -2106,6 +2227,12 @@
 				ask->current_request->granted = TRUE;
 			}
 			break;
+		case ASK_CHANGE_KEYRING_PASSWORD:
+			if (strlen (str) > 0) {
+				ask->current_request->password = g_strdup (str);
+				ask->current_request->granted = TRUE;
+			}
+			break;
 		case ASK_KEYRING_PASSWORD:
 			if (ask->current_request->keyring != NULL) {
 				keyring = ask->current_request->keyring;
@@ -2226,6 +2353,8 @@
 		argv[1] = "-k";
 	} else if (ask_type == ASK_NEW_KEYRING_PASSWORD) {
 		argv[1] = "-n";
+	} else if (ask_type == ASK_CHANGE_KEYRING_PASSWORD) {
+		argv[1] = "-c";
 	} else if (ask_type == ASK_ITEM_READ_WRITE_ACCESS) {
 		argv[1] = "-i";
 	} else if (ask_type == ASK_DEFAULT_KEYRING) {
@@ -2303,6 +2432,15 @@
 			/* iterate */
 			gnome_keyring_ask_iterate (ask);
 		}
+		break;	
+	case GNOME_KEYRING_ACCESS_REQUEST_CHANGE_KEYRING_PASSWORD:
+		if (!launch_ask_helper (ask, ASK_CHANGE_KEYRING_PASSWORD)) {
+			/* no way to allow request, denying */
+			ask->access_requests = g_list_remove (ask->access_requests, request);
+			gnome_keyring_access_request_free (request);
+			/* iterate */
+			gnome_keyring_ask_iterate (ask);
+		}
 		break;
 	case GNOME_KEYRING_ACCESS_REQUEST_DEFAULT_KEYRING:
 		if (!launch_ask_helper (ask, ASK_DEFAULT_KEYRING)) {
@@ -2465,6 +2603,7 @@
 	{ op_get_item_info_or_attributes_collect, op_get_item_acl_execute}, /* GET_ITEM_ACL */
 	{ op_set_item_info_or_attributes_collect, op_set_item_acl_execute}, /* SET_ITEM_ACL */
 	{ NULL, op_set_daemon_display_execute}, /* SET_DAEMON_DISPLAY */
+	{ op_change_keyring_password_collect, op_change_keyring_password_execute }, /*CHANGE_KEYRING_PASSWORD*/
 };
 
 static RETSIGTYPE
Index: gnome-keyring/gnome-keyring-daemon.h
===================================================================
--- gnome-keyring/gnome-keyring-daemon.h	(revision 1)
+++ gnome-keyring/gnome-keyring-daemon.h	(working copy)
@@ -81,6 +81,7 @@
 	GNOME_KEYRING_ACCESS_REQUEST_KEYRING,
 	GNOME_KEYRING_ACCESS_REQUEST_ITEM,
 	GNOME_KEYRING_ACCESS_REQUEST_NEW_KEYRING_PASSWORD,
+	GNOME_KEYRING_ACCESS_REQUEST_CHANGE_KEYRING_PASSWORD,
 	GNOME_KEYRING_ACCESS_REQUEST_DEFAULT_KEYRING
 } GnomeKeyringAccessRequestType;
 
Index: gnome-keyring/gnome-keyring-proto.h
===================================================================
--- gnome-keyring/gnome-keyring-proto.h	(revision 1)
+++ gnome-keyring/gnome-keyring-proto.h	(working copy)
@@ -50,6 +50,7 @@
 
 	/* Add new ops here */
 	GNOME_KEYRING_OP_SET_DAEMON_DISPLAY,
+	GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
 	
 	GNOME_KEYRING_NUM_OPS
 } GnomeKeyringOpCode;
Index: gnome-keyring/gnome-keyring.c
===================================================================
--- gnome-keyring/gnome-keyring.c	(revision 1)
+++ gnome-keyring/gnome-keyring.c	(working copy)
@@ -1030,6 +1030,64 @@
         return res;
 }
 
+gpointer
+gnome_keyring_change_password (const char                                  *keyring,
+		      const char                                  *password,
+		      GnomeKeyringOperationDoneCallback            callback,
+		      gpointer                                     data,
+		      GDestroyNotify                               destroy_data)
+{
+	GnomeKeyringOperation *op;
+	
+	op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+	if (op->state == STATE_FAILED) {
+		return op;
+	}
+	
+	if (!gnome_keyring_proto_encode_op_string_string (op->send_buffer,
+							  GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
+							  keyring, password)) {
+		schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+	}
+
+	op->reply_handler = gnome_keyring_standard_reply;
+	
+	return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_change_password_sync (const char *keyring_name,
+			   const char *password)
+{
+	GString *send, *receive;
+	GnomeKeyringResult res;
+	
+	send = g_string_new (NULL);
+	
+	if (!gnome_keyring_proto_encode_op_string_string (send,
+							  GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
+							  keyring_name, password)) {
+		g_string_free (send, TRUE);
+		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+	}
+	
+ 	receive = g_string_new (NULL);
+	res = run_sync_operation (send, receive);
+	g_string_free (send, TRUE);
+	if (res != GNOME_KEYRING_RESULT_OK) {
+		g_string_free (receive, TRUE);
+		return res;
+	}
+
+	if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+		g_string_free (receive, TRUE);
+		return GNOME_KEYRING_RESULT_IO_ERROR;
+	}
+	g_string_free (receive, TRUE);
+
+	return res;
+}
+
 static void
 gnome_keyring_get_keyring_info_reply (GnomeKeyringOperation *op)
 {
Index: gnome-keyring/gnome-keyring.h
===================================================================
--- gnome-keyring/gnome-keyring.h	(revision 1)
+++ gnome-keyring/gnome-keyring.h	(working copy)
@@ -175,6 +175,13 @@
 						     gpointer                                      data,
 						     GDestroyNotify                                destroy_data);
 GnomeKeyringResult gnome_keyring_delete_sync        (const char                                   *keyring);
+gpointer           gnome_keyring_change_password             (const char                                   *keyring,
+						     const char                                   *password,
+						     GnomeKeyringOperationDoneCallback             callback,
+						     gpointer                                      data,
+						     GDestroyNotify                                destroy_data);
+GnomeKeyringResult gnome_keyring_change_password_sync        (const char                                   *keyring,
+						     const char                                   *password);
 gpointer           gnome_keyring_get_info           (const char                                   *keyring,
 						     GnomeKeyringOperationGetKeyringInfoCallback   callback,
 						     gpointer                                      data,

